    001    // Copyright 2008, 2010, 2011, 2012 The Apache Software Foundation
    002    //
    003    // Licensed under the Apache License, Version 2.0 (the "License");
    004    // you may not use this file except in compliance with the License.
    005    // You may obtain a copy of the License at
    006    //
    007    // http://www.apache.org/licenses/LICENSE-2.0
    008    //
    009    // Unless required by applicable law or agreed to in writing, software
    010    // distributed under the License is distributed on an "AS IS" BASIS,
    011    // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    012    // See the License for the specific language governing permissions and
    013    // limitations under the License.
    014
    015    package org.apache.tapestry5.internal.services;
    016
    017    import org.apache.tapestry5.SymbolConstants;
    018    import org.apache.tapestry5.ioc.annotations.Inject;
    019    import org.apache.tapestry5.ioc.annotations.Symbol;
    020    import org.apache.tapestry5.ioc.internal.util.InternalUtils;
    021    import org.apache.tapestry5.services.BaseURLSource;
    022    import org.apache.tapestry5.services.Request;
    023
    024    public class BaseURLSourceImpl implements BaseURLSource
    025    {
    026        private final Request request;
    027
    028        private String hostname;
    029        private int hostPort;
    030        private int secureHostPort;
    031
    032        public BaseURLSourceImpl(Request request, @Inject @Symbol(SymbolConstants.HOSTNAME) String hostname,
    033                                 @Symbol(SymbolConstants.HOSTPORT) int hostPort, @Symbol(SymbolConstants.HOSTPORT_SECURE) int secureHostPort)
    034        {
    035            this.request = request;
    036            this.hostname = hostname;
    037            this.hostPort = hostPort;
    038            this.secureHostPort = secureHostPort;
    039        }
    040
    041        public String getBaseURL(boolean secure)
    042        {
    043            return String.format("%s://%s%s",
    044                    secure ? "https" : "http",
    045                    hostname(),
    046                    portExtension(secure));
    047        }
    048
    049        private String portExtension(boolean secure)
    050        {
    051            int port = secure ? secureHostPort : hostPort;
    052
    053            // The default for the ports is 0, which means to use Request.serverPort. That's mostly
    054            // for development.
    055            if (port <= 0)
    056            {
    057                port = request.getServerPort();
    058            }
    059
    060            int expectedPort = secure ? 443 : 80;
    061
    062            if (port == expectedPort)
    063            {
    064                return "";
    065            }
    066
    067            return ":" + port;
    068        }
    069
    070        private String hostname()
    071        {
    072
    073            if (InternalUtils.isBlank(hostname))
    074            {
    075                return request.getServerName();
    076            }
    077
    078            // This is common in some PaaS deployments, such as Heroku, where the port is passed in as
    079            // and environment variable.
    080
    081            if (this.hostname.startsWith("$"))
    082            {
    083                return System.getenv(hostname.substring(1));
    084            }
    085
    086            return hostname;
    087        }
    088    }