Changeset 32429 for main/trunk

Show
Ignore:
Timestamp:
06.09.2018 22:32:58 (13 months ago)
Author:
ak19
Message:

solr should only be accessible locally (from localhost, specifically 127.0.0.1) which means over http. This conflicted with the previous design of the properties file for working with http and/or https. Now we have tomcat.port.https and localhost.port.http, both always set. In place of server.protocol that used to contain the default protocol, we now have server.protocols which can be set to a comma separated list of one or both of http and https. Drastic restructuring followed. I think I've tested all but https certification stuff.

Location:
main/trunk/greenstone3
Files:
10 modified

Legend:

Unmodified
Added
Removed
  • main/trunk/greenstone3/build.properties.svn

    r32360 r32429  
    99tomcat.server=localhost 
    1010 
    11 # The default protocol: http, or https for security 
    12 # If you wish to use both, set the default protocol here (https recommended), then 
    13 # uncomment both tomcat.port.http and tomcat.port.https and set them to valid port numbers. 
    14 server.protocol=http 
     11# server.protocols must contain 'http' or 'https' or both (in order of preference) separated by commas 
     12# These specify the protocols you want your Digital Library (DL) to be accessible over.  
     13# The FIRST ONE in the list will be the default. 
     14# NOTE: For https support, you will additionally also need to 
     15# - assign a password to keystore.pass below 
     16# - ensure an unused and valid port number is assigned to tomcat.port.https below 
     17# - set tomcat.server above to the primary domain name of your DL, and 
     18# - run the 'ant setup-https-cert' target to get an official security certificate issued (for which 
     19# you may need admin/sudo permissions) 
     20server.protocols=http 
     21#server.protocols=https 
     22#server.protocols=https,http 
    1523 
    16 # At minimum, the tomcat.port matching the default server.protocol specified above 
    17 # must be enabled (uncommented) below and be set to a valid port number. 
    18 # You're allowed to enable both tomcat.port values here. 
    19 tomcat.port.http=8383 
    20 #tomcat.port.https=8443 
    21 # You must set a password if using https (if tomcat.port.https is uncommented above) 
     24# You must set a password if you turned on https support by including 'https' in server.protocols above 
    2225keystore.pass= 
     26 
     27# Choose valid port numbers that aren't already in use for tomcat.port.https and localhost.port.http: 
     28 
     29# If server.protocols above contains https, then your DL will (additionally) be available over https 
     30# on the port you assign for tomcat.port.https when you make your DL public. 
     31# But if server.protocols does not contain https, then tomcat.port.https will remain unused. 
     32tomcat.port.https=8443 
     33 
     34# When the server is running, http will always be available locally at 127.0.0.1 at localhost.port.http 
     35# If server.protocols above includes http, then your DL will additionally be made public over http 
     36# (on the hostname denoted by tomcat.server at the port number denoted by localhost.port.http) 
     37localhost.port.http=8383 
    2338 
    2439# Tomcat's shutdown port - this may need to be changed if you are running two or more Tomcats 
  • main/trunk/greenstone3/build.xml

    r32427 r32429  
    5757       If not testing can either uncomment this property or set value=false. 
    5858       BEWARE: iff test.mode is true (so https.testing gets set to minus-minus-staging) 
    59        AND server.protocol=https, check-tomcat-running and any other targets running 
    60        an ant http condition to test the default GS DL URL (which will be over https) 
    61        won't work. This is because the testing certificate is not trusted by 
    62        clients, in this case the ant http condition. (Clients that are browsers can 
    63        be set to temporarily trust the testing certificate, but don't know how to make 
    64        ant do that, maybe it needs to be done at Java level.) 
     59       AND the default protocol is https (server.protocols contains https first), the  
     60       check-tomcat-running target and any other targets running an ant http condition 
     61       to test the default GS DL URL (which will be over https) won't work. 
     62       This is because the testing certificate is not trusted by clients, in this case 
     63       the ant http condition. (Clients that are browsers can be set to temporarily 
     64       trust the testing certificate, but don't know how to make ant do that, maybe it 
     65       needs to be done at Java level.) 
    6566       Ant socket conditions to the URL will work because socket tests don't use 
    6667       the protocol, just the host and port. 
     
    118119  </if> 
    119120 
    120  
    121   <!-- If internal.tomcat.port not yet set, work it out based on server.protocol  
    122        Would be great if we could just use nested variables in build.properties 
    123        https://grokbase.com/t/ant/user/04698xjbp3/nested-variables-in-ant 
    124        http://ant.apache.org/faq.html#propertyvalue-as-name-for-property 
    125        http://ant.1045680.n5.nabble.com/Property-expansion-in-macrodef-attributes-td5476406.html 
    126  
    127        https://marc.info/?l=ant-user&m=111231719328847 
    128        http://ant-contrib.sourceforge.net/tasks/tasks/propertycopy.html 
    129        http://www.jguru.com/faq/view.jsp?EID=1072238 
    130        * propfile: 
    131        https://ant.apache.org/manual/Tasks/propertyfile.html 
     121  <if> 
     122    <bool><not><matches string="${server.protocols}" pattern="^\s*(https?|http\s*,\s*https|https\s*,\s*http)\s*$"/></not></bool> 
     123    <fail>@@@@ 
     124      In file build.properties: invalid value for server.protocols. 
     125      It must contain http or https, or both (in order of preference) separated by commas. 
     126    </fail> 
     127  </if> 
     128 
     129  <!--  
    132130       * "valid ports range from 1024–49151" is probably about user assignable ports. 
    133131       But 80 is a valid port for running web servers including GS 
     
    137135    <if> 
    138136      <bool> 
    139       <and> 
    140         <isset property="tomcat.port.http"/> 
    141         <not><matches string="${tomcat.port.http}" pattern="^\d{2,}\s*$"/></not> 
    142       </and>      
     137    <not><matches string="${localhost.port.http}" pattern="^\d{2,}\s*$"/></not> 
    143138      </bool> 
    144139      <fail>... 
    145     ********* ERROR: tomcat.port.http in file build.properties is set to an invalid port number. 
     140    ********* ERROR: localhost.port.http in file build.properties is set to an invalid port number. 
    146141    If port 80 is not possible, user assignable ports range from 1024–49151. 
    147142    But don't choose any port already in use by another application. 
    148     Try setting to tomcat.port.http=8383 
     143    Try setting to localhost.port.http=8383 
    149144      </fail> 
    150145    </if> 
    151146 
     147    <!-- if server.protocols contains https, ensure its port number is valid --> 
    152148    <if> 
    153149      <bool> 
    154150      <and> 
    155         <isset property="tomcat.port.https"/> 
     151        <matches string="${server.protocols}" pattern="https"/> 
    156152        <not><matches string="${tomcat.port.https}" pattern="^\d{2,}\s*$"/></not> 
    157153      </and> 
    158154      </bool> 
    159155      <fail>... 
    160     ********* ERROR: tomcat.port.https in file build.properties is set to an invalid port number. 
     156    ********* ERROR: in file build.properties, server.protocols includes https but 
     157    tomcat.port.https is set to an invalid port number. 
    161158    If port 443 is not possible, user assignable ports range from 1024–49151. 
    162159    But don't choose any port already in use by another application. 
     
    167164    <!--  
    168165     Bail if https is enabled but the keystore password (keystore.pass property) is not set. 
    169      However, keystore.pass has no default value and is therefore not set as a rule. So don't bail when 'ant' is run for the first time to create build.props from build.props.svn. But do bail if running ant.prepare and https enabled and password not set. 
    170      (Maybe put this entire section before the first target: so we only bail after all non-targets are executed so that any other first ever initialisation is completed?) 
     166     However, keystore.pass has no default value and is therefore not set as a rule. 
     167     So don't bail when 'ant' is run for the first time to create build.props from build.props.svn. 
     168     But do bail if running ant.prepare and https enabled and password not set. 
     169     (Maybe put this entire section before the first target: so we only bail after all non-targets 
     170     are executed so that any other first ever initialisation is completed?) 
    171171    --> 
    172172    <if> 
    173173      <bool> 
    174174    <and> 
    175       <isset property="tomcat.port.https"/> 
     175      <matches string="${server.protocols}" pattern="https"/> 
    176176      <or> 
    177177        <not><isset property="keystore.pass"/></not> 
     
    182182      <if> 
    183183    <bool><isset property="first.run"/></bool> 
    184     <echo>IMPORTANT: When tomcat.port.https is set in file build.properties, as now, 
    185     the keystore.pass property must be set to a non-empty value. 
    186     Either comment out tomcat.port.https if you don't want support for https, 
    187     or set keystore.pass.</echo> 
     184    <echo>IMPORTANT: In file build.properties, when property server.protocols includes https, 
     185    as now, the keystore.pass property must be set to a non-empty value. 
     186    Either set server.protocols to http by itself, if you don't want support for https, 
     187    or set keystore.pass if you do want https support.</echo> 
    188188    <else> 
    189189      <fail>... 
    190       ********* ERROR: tomcat.port.https in file build.properties is set, but its required keystore.pass property is not set or is set to the empty string. Choose a password for keystore.pass and set it in build.properties before proceeding. 
     190      ********* ERROR: server.protocols contains https in file build.properties, but the keystore.pass 
     191      property required for obtaining/renewing the https certificate is not set or is set to the empty 
     192      string. Choose a password for keystore.pass and set it in build.properties before proceeding. 
    191193      </fail> 
    192194    </else> 
     
    194196    </if> 
    195197 
    196     <!-- Set the keystore file name for linux versus windows. Ultimately unused/inactive if HTTPS is not enabled and no certificate obtained. We don't have https certification on mac --> 
    197     <condition property="keystore.file" value="fullchain_and_prvtkey.pfx" else="fullchain_and_prvtkey.p12"> 
    198         <istrue value="${current.os.iswindows}"/> 
    199     </condition>     
    200      
     198    <!-- Set the keystore file name for linux versus windows. Ultimately unused/inactive if HTTPS 
     199     isn't enabled and no certificate obtained. We don't yet have https certification on mac --> 
     200    <condition property="keystore.file" value="fullchain_and_prvtkey.pfx" else="fullchain_and_prvtkey.p12"> 
     201      <istrue value="${current.os.iswindows}"/> 
     202    </condition>     
     203 
     204    <!-- Originally, https redirectPort when using regular http port 8383 
     205     was always fixed at 8443. Now we use redirectPort=tomcat.port.https. 
     206    --> 
     207    <property name="https.redirect.port" value="${tomcat.port.https}"/> 
     208 
     209    <!-- The default protocol to be used is the FIRST in the comma separated list for server.protocols  
     210    The default public tomcat port depends on the default server protocol 
     211    --> 
     212    <if> 
     213      <bool><matches string="${server.protocols}" pattern="^https"/></bool> 
     214      <property name="default.server.protocol" value="https"/> 
     215      <property name="default.tomcat.port" value="${tomcat.port.https}"/>       
     216      <else> 
     217    <property name="default.server.protocol" value="http"/> 
     218    <property name="default.tomcat.port" value="${localhost.port.http}"/>    
     219      </else> 
     220    </if> 
     221     
     222 
     223    <!-- For setting filter tokens. 
     224     Used to set up server.xml when configuring tomcat --> 
     225    <property name="comment.start" value="&lt;!--" /> 
     226    <property name="comment.end" value="--&gt;" /> 
     227 
    201228    <!--  
    202      1. Using the macrodef task from ant 1.6+ (https://ant.apache.org/manual/Tasks/macrodef.html) 
    203      to define "propertycopy" macro that then allows us to use nested variables in build.xml 
    204      (Is there any way to use nested variables in build.properties?) 
    205      Defining the propertycopy macro: 
    206      http://ant.apache.org/faq.html#propertyvalue-as-name-for-property 
     229     If https is enabled, regardless of whether it is the default protocol, 
     230     there's some more work to do: 
     231     - 
     232     - if https is not enabled, comment out its Connecter element in server.xml 
     233    -->     
     234    <if> 
     235      <bool><matches string="${server.protocols}" pattern="https"/></bool>       
     236      <property name="https.comment.out.start" value=""/> 
     237      <property name="https.comment.out.end" value=""/> 
     238 
     239      <else>     
     240    <property name="https.comment.out.start" value="${comment.start}"/> 
     241    <property name="https.comment.out.end" value="${comment.end}"/> 
     242      </else> 
     243    </if> 
     244 
     245    <!-- if server.protocols doesn't contain http, then http is only to be locally available, 
     246     e.g. for solr servlet on 127.0.0.1  
     247     In that case, see https://serverfault.com/questions/218666/how-to-configure-tomcat-to-only-listen-to-127-0-0-1 
    207248    --> 
    208     <macrodef name="propertycopy"> 
    209       <attribute name="name"/> 
    210       <attribute name="from"/> 
    211       <sequential> 
    212     <property name="@{name}" value="${@{from}}"/> 
    213       </sequential> 
    214     </macrodef> 
    215     <!-- 
    216     2. Now can use the 'propertycopy' macro defined above to allow us to use a property's value 
    217     (e.g. server.protocol's value) as a part of the name for a property. 
    218     So we want do something like ${tomcat.port.${server.protocol}}, which, if server.protocol=http, 
    219     we'd like it to turn into tomcat.port.http. Then we want to use the constructed variable name 
    220     to assign its value to a new variable. Use is as follows: 
    221        propertycopy name="tomcat.port.protocol" from="tomcat.port.${server.protocol}" 
    222     http://ant.1045680.n5.nabble.com/Property-expansion-in-macrodef-attributes-td5476406.html 
     249    <condition property="restrict.http.to.local" value="false" else="true"> 
     250      <matches string="${server.protocols}" pattern="http($|\s+|,)"/> 
     251    </condition> 
     252     
     253    <condition property="http.address.restriction" value="address=&quot;127.0.0.1&quot;" else=""> 
     254      <istrue value="${restrict.http.to.local}"/> 
     255    </condition> 
     256 
     257    <!-- No certificates for localhost: https://letsencrypt.org/docs/certificates-for-localhost/  
     258    But 'localhost' (or actually, 127.0.0.1) needed for solr: solr servlet not accessible to outside world  
    223259    --> 
    224     <propertycopy name="internal.tomcat.port" from="tomcat.port.${server.protocol}"/> 
    225     <if> 
    226       <bool><matches string="${internal.tomcat.port}" pattern="tomcat\.port"/></bool> 
    227       <fail>... 
    228       ********* ERROR: Unable to set tomcat.port: 
    229       In file build.properties server.protocol=${server.protocol} and requires at minimum that its 
    230       matching tomcat.port.${server.protocol} property line is enabled and set to a valid port number.</fail> 
    231     </if> 
    232  
    233   <!-- If we got here, we got a valid tomcat port. Set tomcat.port in build.properties 
    234        Set autogenerated properties (properties we calculate here in build.xml) 
    235        in build.properties. https://ant.apache.org/manual/Tasks/propertyfile.html 
    236        For now only internal.tomcat.port is determined by build.xml 
    237        and written out to build.properties as tomcat.port. 
    238        Internally, this file still uses internal.tomcat.port as any old value 
    239        read in from build.properties for tomcat.port can't be changed in memory 
    240        even though we can write it back out again to build.properties. 
    241   --> 
    242   <echo>Using tomcat port: ${internal.tomcat.port}</echo> 
    243  
    244   <!-- We're no longer writing out a tomcat.port property to build.properties based on what we've determined this should be: 
    245   - the perl code only cares about the final GS3 URL, which is determined by this ant build file and uses internal.tomcat.port 
    246   - and the GS3 Java src code has been updated to work without tomcat.port in build.properties --> 
    247   <!-- 
    248   <propertyfile file="build.properties"> 
    249     <entry key="tomcat.port" value="${internal.tomcat.port}"/> 
    250   </propertyfile> 
    251   --> 
    252  
    253   <!-- For setting filter tokens. 
    254        Used to set up server.xml when configuring tomcat --> 
    255   <property name="comment.start" value="&lt;!--" /> 
    256   <property name="comment.end" value="--&gt;" /> 
    257   <!-- originally, https redirectPort when using regular http port 8383 
    258   was always fixed at 8443. Now we use redirectPort=tomcat.port.https unless 
    259   it's not set, in which case we fall back to the original value of 8443. --> 
    260   <condition property="https.redirect.port" value="${tomcat.port.https}" else="8443">  
    261     <isset property="tomcat.port.https"/> 
    262   </condition> 
    263  
    264   <!-- if http is not enabled, comment out its Connecter element in server.xml --> 
    265   <condition property="http.comment.out.start" value="" else="${comment.start}"> 
    266     <isset property="tomcat.port.http"/> 
    267   </condition> 
    268   <condition property="http.comment.out.end" value="" else="${comment.end}"> 
    269     <isset property="tomcat.port.http"/> 
    270   </condition> 
    271   <!-- if https is not enabled, comment out its Connecter element in server.xml --> 
    272   <condition property="https.comment.out.start" value="" else="${comment.start}"> 
    273     <isset property="tomcat.port.https"/> 
    274   </condition> 
    275   <condition property="https.comment.out.end" value="" else="${comment.end}"> 
    276     <isset property="tomcat.port.https"/> 
    277   </condition> 
     260    <property name="local.http.url" value="http://127.0.0.1:${localhost.port.http}"/> 
    278261 
    279262    <!-- On linux, if testing https certification, pass in minus-minus-staging. If not testing on linux, nothing extra to pass in. 
     
    10521035 
    10531036  <target name="get-default-servlet-url"> 
    1054     <echo>${server.protocol}://${tomcat.server}:${internal.tomcat.port}${app.path}${server.default.servlet}</echo> 
    1055   </target> 
    1056  
     1037    <echo>${default.server.protocol}://${tomcat.server}:${default.tomcat.port}${app.path}${server.default.servlet}</echo> 
     1038  </target> 
     1039 
     1040  <!-- solr should only be accessible locally, which therefore also means only over http. 
     1041  But for http,  use 127.0.0.1 instead of localhost (as localhost can be mapped to something other than 127.0.0.1 
     1042  and is therefore not safe). See https://letsencrypt.org/docs/certificates-for-localhost/ --> 
    10571043  <target name="get-solr-servlet-url"> 
    1058     <echo>${server.protocol}://${tomcat.server}:${internal.tomcat.port}/${solr.context}</echo> 
     1044    <!--<echo>${default.server.protocol}://${tomcat.server}:${default.tomcat.port}/${solr.context}</echo>--> 
     1045    <echo>http://127.0.0.1:${localhost.port.http}/${solr.context}</echo> 
    10591046  </target> 
    10601047 
     
    11461133    </if> 
    11471134    <if><bool><isset property="install.flax"/></bool> 
    1148         <property name="url" value="${server.protocol}://${tomcat.server}:${internal.tomcat.port}${app.path}/flax"/> 
     1135        <property name="url" value="${default.server.protocol}://${tomcat.server}:${default.tomcat.port}${app.path}/flax"/> 
    11491136    <else> 
    1150         <property name="url" value="${server.protocol}://${tomcat.server}:${internal.tomcat.port}${app.path}/"/> 
     1137        <property name="url" value="${default.server.protocol}://${tomcat.server}:${default.tomcat.port}${app.path}/"/> 
    11511138    </else> 
    11521139    </if> 
     
    12011188  <target name="accept-properties" unless="properties.accepted"> 
    12021189    <input addproperty="properties.ok" validargs="y,n">The following properties (among others) are being used from a build.properties file found in this directory: 
    1203       server.protocol=${server.protocol} 
     1190      server.protocols=${server.protocols}       
    12041191      tomcat.server=${tomcat.server} 
    1205       <!--tomcat.port=${internal.tomcat.port}--> 
    1206       tomcat.port.http=${tomcat.port.http} 
    12071192      tomcat.port.https=${tomcat.port.https} 
     1193      localhost.port.http=${localhost.port.http} 
     1194 
     1195         default.server.protocol=${default.server.protocol} 
     1196         default.tomcat.port=${default.tomcat.port} 
     1197         Local base HTTP URL used by Greenstone: ${local.http.url} 
     1198 
    12081199      tomcat.installed.path=${tomcat.installed.path} (this is the location of Tomcat's base dir if it is already installed) 
    12091200      proxy.host=${proxy.host} 
     
    12411232      </or> 
    12421233    </condition> 
    1243      
    1244     <echo>internal.tomcat.port = ${internal.tomcat.port}</echo> 
    12451234 
    12461235    <condition property="proxy.present"> 
     
    15511540    <filter token="gsdl3writablehome" value="${src.gsdl3.writablehome.unix}"/> 
    15521541    <filter token="gsdl3version" value="${app.version}"/> 
    1553     <filter token="server.protocol" value="${server.protocol}"/> 
     1542    <filter token="server.protocols" value="${server.protocols}"/> 
     1543    <filter token="default.server.protocol" value="${default.server.protocol}"/> 
    15541544    <filter token="tomcat.server" value="${tomcat.server}"/> 
    1555     <filter token="tomcat.port" value="${internal.tomcat.port}"/> 
    1556     <!-- add filters for tomcat.port.http and tomcat.port.https depending on if 
    1557      these are set. If any is not set, set its filter to the empty string --> 
    1558     <if> 
    1559       <bool><isset property="tomcat.port.http"/></bool> 
    1560       <filter token="tomcat.port.http" value="${tomcat.port.http}"/> 
    1561       <else><filter token="tomcat.port.http" value=""/></else> 
    1562     </if> 
    1563     <if> 
    1564       <bool><isset property="tomcat.port.https"/></bool> 
    1565       <filter token="tomcat.port.https" value="${tomcat.port.https}"/> 
    1566       <else><filter token="tomcat.port.https" value=""/></else> 
    1567     </if> 
     1545    <filter token="default.tomcat.port" value="${default.tomcat.port}"/> 
     1546    <filter token="localhost.port.http" value="${localhost.port.http}"/> 
     1547    <filter token="tomcat.port.https" value="${tomcat.port.https}"/>     
    15681548    <filter token="greenstone.context" value="${greenstone.context}"/> 
    15691549    <filter token="solr.context" value="${solr.context}"/> 
     
    17401720        See https://ant.apache.org/manual/Tasks/antcall.html --> 
    17411721    <antcall target="start"> 
    1742         <param name="tomcat.port.http" value="80"/> 
    1743         <param name="internal.tomcat.port" value="80"/> 
    1744         <param name="http.comment.out.start" value=""/> 
    1745         <param name="http.comment.out.end" value=""/> 
     1722        <param name="localhost.port.http" value="80"/> 
     1723        <param name="default.tomcat.port" value="80"/> 
     1724        <param name="http.address.restriction" value=""/><!-- don't prevent public access over http of port 80 --> 
    17461725        <param name="https.comment.out.start" value="${comment.start}"/> 
    17471726        <param name="https.comment.out.end" value="${comment.end}"/> 
     
    17791758    <!-- stop the tomcat running on port 80 --> 
    17801759    <antcall target="stop"> 
    1781         <param name="tomcat.port.http" value="80"/> 
    1782         <param name="internal.tomcat.port" value="80"/> 
    1783         <param name="http.comment.out.start" value=""/> 
    1784         <param name="http.comment.out.end" value=""/> 
     1760        <param name="localhost.port.http" value="80"/> 
     1761        <param name="default.tomcat.port" value="80"/> 
     1762        <param name="http.address.restriction" value=""/> 
    17851763        <param name="https.comment.out.start" value="${comment.start}"/> 
    17861764        <param name="https.comment.out.end" value="${comment.end}"/> 
     
    20252003        <filter token="shutdown-port" value="${tomcat.shutdown.port}"/> 
    20262004    <filter token="https.redirect.port" value="${https.redirect.port}"/> 
    2027     <filter token="tomcat.port.http" value="${tomcat.port.http}"/> 
     2005    <filter token="localhost.port.http" value="${localhost.port.http}"/> 
    20282006    <filter token="tomcat.port.https" value="${tomcat.port.https}"/> 
    20292007    <!-- Relative path preferred for keystore.file, in case tomcat is moved elsewhere --> 
     
    20402018    <filter token="keystore.type" value="PKCS12"/> 
    20412019    <filter token="keystore.pass" value="${keystore.pass}"/> 
    2042     <filter token="http.comment.out.start" value="${http.comment.out.start}"/> 
    2043     <filter token="http.comment.out.end" value="${http.comment.out.end}"/> 
     2020    <!-- 
     2021        if server.protocols doesn't contain http, then http is only to be locally available (e.g. for solr servlet on 127.0.0.1) 
     2022        In that case, see https://serverfault.com/questions/218666/how-to-configure-tomcat-to-only-listen-to-127-0-0-1 
     2023    --> 
     2024    <filter token="http.address.restriction" value="${http.address.restriction}"/> 
     2025    <filter token="restrict.http.to.local" value="${restrict.http.to.local}"/> 
    20442026    <filter token="https.comment.out.start" value="${https.comment.out.start}"/> 
    20452027    <filter token="https.comment.out.end" value="${https.comment.out.end}"/> 
     
    21662148    <waitfor maxwait="5" maxwaitunit="second"> 
    21672149      <and> 
    2168         <socket server="${tomcat.server}" port="${internal.tomcat.port}"/> 
    2169         <http url="${server.protocol}://${tomcat.server}:${internal.tomcat.port}${app.path}/index.html"/> 
     2150        <socket server="${tomcat.server}" port="${default.tomcat.port}"/> 
     2151    <!--<http url="${default.server.protocol}://${tomcat.server}:${default.tomcat.port}${app.path}/index.html"/>--> 
     2152    <http url="${local.http.url}${app.path}/index.html"/> 
    21702153      </and> 
    21712154    </waitfor> 
     
    21762159    <if><bool><istrue value="${tomcat.isstarted}"/></bool> 
    21772160      <echo>**************************************</echo> 
    2178       <echo>A WEB SERVER IS ALREADY RUNNING ON ${server.protocol}://${tomcat.server}:${internal.tomcat.port}. NOT STARTING.</echo> 
     2161      <echo>A WEB SERVER IS ALREADY RUNNING ON ${default.server.protocol}://${tomcat.server}:${default.tomcat.port} (${local.http.url}). NOT STARTING.</echo> 
    21792162      <echo>**************************************</echo> 
    21802163      <else> 
     
    22312214    <waitfor maxwait="5" maxwaitunit="second"> 
    22322215      <and> 
    2233         <socket server="${tomcat.server}" port="${internal.tomcat.port}"/> 
    2234         <http url="${server.protocol}://${tomcat.server}:${internal.tomcat.port}${app.path}/index.html"/> 
     2216        <socket server="${tomcat.server}" port="${default.tomcat.port}"/> 
     2217        <!--<http url="${default.server.protocol}://${tomcat.server}:${default.tomcat.port}${app.path}/index.html"/>--> 
     2218        <http url="${local.http.url}${app.path}/index.html"/> 
    22352219      </and> 
    22362220    </waitfor> 
     
    22412225  <target name="reconfigure" description="Reconfigure the message router"> 
    22422226    <waitfor maxwait="5" maxwaitunit="second"> 
    2243       <http url="${server.protocol}://${tomcat.server}:${internal.tomcat.port}${app.path}${server.default.servlet}?a=s&amp;sa=c"/> 
     2227      <!--<http url="${default.server.protocol}://${tomcat.server}:${default.tomcat.port}${app.path}${server.default.servlet}?a=s&amp;sa=c"/>--> 
     2228      <http url="${local.http.url}${app.path}${server.default.servlet}?a=s&amp;sa=c"/> 
    22442229    </waitfor> 
    22452230  </target> 
     
    22482233  <target name="reconfigure-collection" description="Reconfigure the collection"> 
    22492234    <waitfor maxwait="5" maxwaitunit="second"> 
    2250       <http url="${server.protocol}://${tomcat.server}:${internal.tomcat.port}${app.path}${server.default.servlet}?a=s&amp;sa=c&amp;sc=${collection}"/> 
     2235      <!--<http url="${default.server.protocol}://${tomcat.server}:${default.tomcat.port}${app.path}${server.default.servlet}?a=s&amp;sa=c&amp;sc=${collection}"/>--> 
     2236      <http url="${local.http.url}${app.path}${server.default.servlet}?a=s&amp;sa=c&amp;sc=${collection}"/> 
    22512237    </waitfor> 
    22522238  </target> 
     
    22812267  <target name="check-tomcat-running"> 
    22822268    <condition property="tomcat.isrunning"> 
    2283       <!--<http url="${server.protocol}://${tomcat.server}:${internal.tomcat.port}${app.path}"/>--> 
    2284       <http url="${server.protocol}://${tomcat.server}:${internal.tomcat.port}"/> 
     2269      <!--<http url="${default.server.protocol}://${tomcat.server}:${default.tomcat.port}${app.path}"/>--> 
     2270      <!--<http url="${default.server.protocol}://${tomcat.server}:${default.tomcat.port}"/>--><!-- untrusted certificates won't work, so don't test https urls--> 
     2271      <http url="${local.http.url}"/><!-- testing the local http url instead --> 
    22852272    </condition> 
    22862273  </target> 
     
    22892276      <target name="verbose-check-tomcat-running"> 
    22902277      <condition property="tomcat.isrunning" value="true" else="false"> 
    2291       <http url="${server.protocol}://${tomcat.server}:${internal.tomcat.port}"/> 
     2278      <http url="${default.server.protocol}://${tomcat.server}:${default.tomcat.port}"/> 
     2279      <http url="${local.http.url}"/> 
    22922280      </condition> 
    22932281      <echo>Tomcat is running: ${tomcat.isrunning}</echo> 
     
    23092297  <target name="check-tomcat-started"> 
    23102298    <condition property="tomcat.isstarted"> 
    2311       <http url="${server.protocol}://${tomcat.server}:${internal.tomcat.port}"/> 
     2299      <!--<http url="${default.server.protocol}://${tomcat.server}:${default.tomcat.port}"/>--> 
     2300      <http url="${local.http.url}"/> 
    23122301    </condition> 
    23132302  </target> 
     
    23262315     <echo>Waiting for the server to shutdown... (${wait.numchecks} seconds max)</echo> 
    23272316     <waitfor maxwait="${wait.numchecks}" maxwaitunit="second" checkevery="1" checkeveryunit="second" timeoutproperty="tomcat.timedout"> 
    2328        <not><socket server="${tomcat.server}" port="${internal.tomcat.port}"/></not> 
     2317       <not><socket server="${tomcat.server}" port="${default.tomcat.port}"/></not> 
    23292318     </waitfor> 
    23302319      
     
    23342323       </bool> 
    23352324       <property name="tomcat.isrunning" value="true"/> 
    2336        <echo>WARNING: Checked the socket ${wait.numchecks} times, but port ${internal.tomcat.port} is still busy.</echo> 
     2325       <echo>WARNING: Checked the socket ${wait.numchecks} times, but port ${default.tomcat.port} is still busy.</echo> 
    23372326       <else> 
    23382327     <echo>Tomcat is stopped.</echo> 
     
    26062595      <classpath refid="compile.classpath"/> 
    26072596      <arg value="-l"/> 
    2608       <arg value="${server.protocol}://${tomcat.server}:${internal.tomcat.port}${app.path}/servlet/AxisServlet"/> 
     2597      <arg value="${default.server.protocol}://${tomcat.server}:${default.tomcat.port}${app.path}/servlet/AxisServlet"/> 
    26092598      <arg file="${basedir}/resources/soap/deploy.wsdd"/> 
    26102599    </java> 
     
    26222611      <classpath refid="compile.classpath"/> 
    26232612      <arg value="-l"/> 
    2624       <arg value="${server.protocol}://${tomcat.server}:${internal.tomcat.port}${app.path}/servlet/AxisServlet"/> 
     2613      <arg value="${default.server.protocol}://${tomcat.server}:${default.tomcat.port}${app.path}/servlet/AxisServlet"/> 
    26252614      <arg file="${basedir}/resources/soap/undeploy.wsdd"/> 
    26262615    </java> 
     
    26542643  <target name="get-undeploy-service-name" unless="axis.undeploy.servicename"> 
    26552644    <input addproperty="axis.undeploy.servicename" defaultvalue="localsite">Please enter the full name of the service you wish to undeploy. 
    2656 To find out which web services you've got deployed, point your browser to ${server.protocol}://${tomcat.server}:${internal.tomcat.port}/greenstone3/services  
     2645To find out which web services you've got deployed, point your browser to ${default.server.protocol}://${tomcat.server}:${default.tomcat.port}/greenstone3/services  
    26572646Or press Enter for undeploying the default:localsite /&gt;</input> 
    26582647     <echo>Name of service to undeploy: ${axis.undeploy.servicename}</echo> 
     
    39533942                <java classname="org.junit.runner.JUnitCore" fork="true"> 
    39543943                    <arg value="gstests.TestClass"/> 
    3955                     <jvmarg value="-DSERVERURL=${server.protocol}://${tomcat.server}:${internal.tomcat.port}${app.path}${server.default.servlet} "/> 
     3944                    <jvmarg value="-DSERVERURL=${default.server.protocol}://${tomcat.server}:${default.tomcat.port}${app.path}${server.default.servlet} "/> 
    39563945                    <classpath> 
    39573946                        <fileset dir="${basedir}/ext/testing/lib/java"> 
  • main/trunk/greenstone3/resources/tomcat/server_tomcat7.xml.svn

    r32349 r32429  
    6868         Define a non-SSL HTTP/1.1 Connector on port @port@ 
    6969    --> 
    70     @http.comment.out.start@ 
    71     <Connector executor="tomcatThreadPool" 
    72            port="@tomcat.port.http@" protocol="HTTP/1.1" 
     70    <Connector executor="tomcatThreadPool" @http.address.restriction@ 
     71           port="@localhost.port.http@" protocol="HTTP/1.1" 
    7372               connectionTimeout="20000" 
    7473               redirectPort="@https.redirect.port@" 
     
    7978               URIEncoding="UTF-8" 
    8079           /> 
    81     @http.comment.out.end@ 
    8280    <!-- A "Connector" using the shared thread pool--> 
    8381    <!-- 
    84     <Connector executor="tomcatThreadPool" 
    85                port="@tomcat.port.http@" protocol="HTTP/1.1" 
     82    <Connector executor="tomcatThreadPool" @http.address.restriction@ 
     83               port="@localhost.port.http@" protocol="HTTP/1.1" 
    8684               connectionTimeout="20000" 
    8785               redirectPort="@https.redirect.port@" /> 
  • main/trunk/greenstone3/resources/web/global.properties.svn

    r32379 r32429  
    1515 
    1616# tomcat info 
    17 server.protocol=@server.protocol@ 
     17server.protocol=@default.server.protocol@ 
    1818tomcat.server=@tomcat.server@ 
    19 tomcat.port=@tomcat.port@ 
    20 tomcat.port.http=@tomcat.port.http@ 
    21 tomcat.port.https=@tomcat.port.https@ 
     19tomcat.port=@default.tomcat.port@ 
    2220tomcat.context=@greenstone.context@ 
    2321solr.context=@solr.context@ 
    2422derby.server.port=@derbyserver.port@ 
    2523derby.server=@derbyserver@ 
     24 
     25server.protocols=@server.protocols@ 
     26tomcat.port.https=@tomcat.port.https@ 
     27localhost.protocol.http=http 
     28localhost.server.http=127.0.0.1 
     29localhost.port.http=@localhost.port.http@ 
     30restrict.http.to.local=@restrict.http.to.local@ 
     31 
    2632 
    2733## Proxy setup - set these if you are behind a firewall and you want services that access the internet 
  • main/trunk/greenstone3/src/java/org/greenstone/gsdl3/service/FedoraServiceProxy.java

    r32419 r32429  
    181181        return false; 
    182182    } catch(Exception e) { 
    183         logger.error("Error instantiating the interface to the Fedora Repository:\n", e); // second parameter prints e's stacktrace 
     183        logger.error("Error instantiating the interface to the Fedora Repository: " + e.getMessage() + "\n", e); // second parameter prints e's stacktrace 
    184184        return false; // configure has failed 
    185185    }  
  • main/trunk/greenstone3/src/java/org/greenstone/gsdl3/util/ServletRealmCheck.java

    r32419 r32429  
    125125         
    126126    } catch (Exception ex) { 
     127        System.err.println("Got exception " + ex.getMessage()); 
    127128        ex.printStackTrace(); 
    128129    } finally { 
  • main/trunk/greenstone3/src/java/org/greenstone/server/Server3.java

    r32419 r32429  
    2828            protocolPortProps = new ProtocolPortProperties(config_properties); 
    2929        } catch(Exception e) { 
    30             String errorMsg = "Error with port/protocol in " + config_properties_file + ": " + protocolPortProps.getErrorMsg(); 
     30            String errorMsg = "@@@ Error with ports/protocol in " + config_properties_file + ": " + e.getMessage(); 
    3131 
    3232            // print it everywhere, because port/protocol misconfiguration is a fatal error and we're exiting 
    33             logger_.error(errorMsg); 
     33            logger_.error(errorMsg, e); 
    3434            System.err.println(errorMsg); 
    3535            // If error, then quit this app as soon as possible 
     
    3737        } 
    3838         
    39         Property = protocolPortProps.legacyMode ? new Server3Property() : new Server3Property(protocolPortProps.getProtocol()); 
     39        Property = new Server3Property(protocolPortProps.getDefaultPortPropertyName());  
     40               // defaultPortPropertyName can be 'localhost.port.http' or 'tomcat.port.https' 
     41               // depending on which of http and https is the first value of 'server.protocols' 
    4042 
    4143        String frame_title = dictionary.get("ServerControl.Frame_Title"); 
  • main/trunk/greenstone3/src/java/org/greenstone/server/Server3Property.java

    r32357 r32429  
    1414    } 
    1515 
    16     Server3Property(String protocol) 
     16    Server3Property(String defaultPortPropertyName) 
    1717    { 
    1818    // Initialising customised final variables  
    1919    // Version number, WEB_PORT, autoenter, startbrowser 
    2020    // For GS3, the last two are controlled by the same property 
    21     super("3", "tomcat.port."+protocol, "server.auto.start", "server.auto.start",  
     21    super("3", defaultPortPropertyName, "server.auto.start", "server.auto.start",  
    2222          "server.keep.port", "server.external.access"); 
    2323    } 
  • main/trunk/greenstone3/src/java/org/greenstone/util/GlobalProperties.java

    r32357 r32429  
    3838    private static String gsdl3_writablehome = null; 
    3939    private static String gsdl3_web_address = null; 
    40     private static String full_gsdl3_web_address = null; 
    41  
    42     private static String http_full_gsdl3_web_address = null; 
    43     private static String https_full_gsdl3_web_address = null; 
     40    private static String full_gsdl3_web_address = null; // for the default protocol 
     41 
     42    private static String http_full_gsdl3_web_address = null; // if http or both protocols supported 
     43    private static String https_full_gsdl3_web_address = null; // if https or both protocols supported 
     44 
     45    // The locally accessible url such as for solr is always available at http://127.0.0.1:<httpPort> 
     46    // regardless of whether http is listed as one of the server protocols 
     47    private static String localhost_http_web_address = null; 
    4448 
    4549    /** get the value of the property 'key'. returns null if not found */ 
     
    8185    { 
    8286        return full_gsdl3_web_address; 
     87    } 
     88 
     89    public static String getLocalHttpBaseAddress() 
     90    { 
     91        return localhost_http_web_address; 
    8392    } 
    8493 
     
    155164            String protocolSpecifier = null, hostSpecifier = null, portSpecifier = null, contextSpecifier = null; 
    156165 
    157             //protocol 
     166            // default protocol 
    158167            protocolSpecifier = properties.getProperty("server.protocol"); 
    159168            if (protocolSpecifier == null || protocolSpecifier.equals("")) 
     
    180189            } 
    181190 
    182             //port 
     191            //default port (port for the default protocol) 
    183192            portSpecifier = properties.getProperty("tomcat.port"); // support for legacy tomcat.port? 
    184             if(portSpecifier == null) { 
    185                 portSpecifier = protocolSpecifier.startsWith("https") ? properties.getProperty("tomcat.port.https") : properties.getProperty("tomcat.port.http"); 
    186             } 
    187193            if (portSpecifier == null || portSpecifier.equals("")  
    188194                || (protocolSpecifier.equals("http://") && portSpecifier.equals("80")) 
     
    214220            gsdl3_web_address = contextSpecifier; 
    215221 
     222            // Set the always available internal root address that is locally accessible (http://127.0.0.1:<httpPort>) 
     223            // Used by solr.  
     224            String httpPort = properties.getProperty("localhost.port.http"); 
     225            localhost_http_web_address = properties.getProperty("localhost.protocol.http") + "://" 
     226                + properties.getProperty("localhost.server.http") // always uses 127.0.0.1 (not localhost, which can be modified and is therefore unsafe!) 
     227                + httpPort; 
     228 
     229 
     230 
    216231            // set the http and https variants of the full web address, if they're meant to be available 
    217             if(protocolSpecifier.startsWith("https")) { // check the default protocol, then set the address for the other protocol too 
     232            // First check the default protocol, then set the web address for the other protocol too 
     233            String supportedProtocols = properties.getProperty("server.protocols", "http"); 
     234            String isHttpRestrictedToLocal = properties.getProperty("restrict.http.to.local", "true"); 
     235 
     236            if(protocolSpecifier.startsWith("https")) { 
    218237                https_full_gsdl3_web_address = full_gsdl3_web_address; 
    219238 
    220                 // and set http version, if sufficient properties are available 
    221                 String httpPort = properties.getProperty("tomcat.port.http"); 
    222                 if(httpPort != null && !httpPort.equals("")) { 
     239                // and set http version of URL, if http is made public (if http is in server.protocols list) 
     240                if(isHttpRestrictedToLocal.equals("false")) {                
    223241                http_full_gsdl3_web_address = "http://" + hostSpecifier + httpPort + contextSpecifier; 
    224242                } 
     
    226244                http_full_gsdl3_web_address = full_gsdl3_web_address; 
    227245 
    228                 // and set https version, if sufficient properties are available 
    229                 String httpsPort = properties.getProperty("tomcat.port.https"); 
    230                 if(httpsPort != null && !httpsPort.equals("")) { 
     246                // and set https version, if https enabled 
     247                if(supportedProtocols.contains("https")) { 
     248                String httpsPort = properties.getProperty("tomcat.port.https"); 
    231249                https_full_gsdl3_web_address = "https://" + hostSpecifier + httpsPort + contextSpecifier; 
    232250                } 
  • main/trunk/greenstone3/src/java/org/greenstone/util/ProtocolPortProperties.java

    r32419 r32429  
    2222 
    2323/* 
    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, 
    2525 * 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.) 
    2829 * 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. 
    2935 */ 
    30 public class ProtocolPortProperties { 
    31  
    32     public final boolean legacyMode; // true if before https protocol supported 
     36public class ProtocolPortProperties {    
    3337 
    3438    public static final int ALL_CORRECT = 0; 
    3539    public static final int SECONDARY_PORT_NON_NUMERIC = 1; 
    3640    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 String 
    48     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; 
    5054    //private int portNum = -1; // port that matches protocol as int 
    5155 
    5256    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) 
    5666    public String getPort() { return port; } 
     67 
     68    // httpPort is always set, but http may or may not be public 
    5769    public String getHttpPort() { return httpPort; } 
     70    // httpsPort is null if https not supported 
    5871    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; } 
    6082 
    6183    public String getErrorMsg() { return errorMsg; } 
     
    6486    public boolean hadError() { return errorCode != ALL_CORRECT; } 
    6587 
    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 
    6899    public ProtocolPortProperties(Properties props) throws Exception { 
    69100    this(props, false); 
    70101    } 
    71102 
     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. 
    72107    public ProtocolPortProperties(Properties props, boolean recover) throws Exception 
    73108    { 
    74109    StringBuffer msg = new StringBuffer(); 
    75110     
    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; 
    101142        } 
    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 
    163159        if(httpPort != null) { 
    164160        try { 
    165161            Integer.parseInt(httpPort); 
    166162        } catch(NumberFormatException nfe) { 
    167             msg.append("\nInvalid port specified for over http: not numeric."); 
     163            msg.append("\nInvalid localhost.port.http specified: must be numeric."); 
    168164            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 
    176168            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"); 
    181171            } 
    182172        } 
     
    187177            Integer.parseInt(httpsPort); 
    188178        } catch(NumberFormatException nfe) { 
    189             msg.append("\nInvalid port specified for over https: not numeric."); 
     179            msg.append("\nInvalid port specified for over https (tomcat.port.https): must be numeric."); 
    190180            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 
    198184            errorCode = SECONDARY_PORT_NON_NUMERIC; 
    199             if(recover) { 
    200                 msg.append("\nNot using this port"); 
    201             } 
    202185            httpsPort = null; 
     186            if(recover) msg.append("\nNot using this port"); 
    203187            } 
    204188        } 
     
    206190    } 
    207191     
     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    } 
    208197 
    209198    if(recover) { 
    210199        msg.append("\nFalling back to port ").append(port).append(" and protocol ").append(protocol).append("."); 
    211200    } 
    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. 
    215201     
    216202    errorMsg = msg.toString();