1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 package io.wcm.handler.url.impl;
21
22 import java.util.Enumeration;
23
24 import org.apache.commons.lang3.StringUtils;
25 import org.apache.commons.lang3.Strings;
26 import org.apache.sling.api.SlingHttpServletRequest;
27 import org.apache.sling.api.adapter.Adaptable;
28 import org.jetbrains.annotations.NotNull;
29 import org.jetbrains.annotations.Nullable;
30 import org.slf4j.Logger;
31 import org.slf4j.LoggerFactory;
32
33
34
35
36
37 final class UrlPrefix {
38
39
40
41
42 public static final String AUTO_DETECTION = "<auto>";
43
44 static final String HTTP_HEADER_X_FORWARDED_HOST = "X-Forwarded-Host";
45 static final String HTTP_HEADER_X_FORWARDED_PROTO = "X-Forwarded-Proto";
46 static final String HTTP_HEADER_HOST = "Host";
47 static final String HTTP_HEADER_X_FORWARDED_SSL = "X-Forwarded-SSL";
48 static final String VALUE_ON = "on";
49
50 private static final Logger log = LoggerFactory.getLogger(UrlPrefix.class);
51
52 private UrlPrefix() {
53
54 }
55
56
57
58
59
60
61
62 static @Nullable String applyAutoDetection(@Nullable String configuredUrlPrefix, @NotNull Adaptable adaptable) {
63 String urlPrefix = configuredUrlPrefix;
64 if (Strings.CS.contains(configuredUrlPrefix, AUTO_DETECTION)) {
65
66 urlPrefix = StringUtils.trimToNull(Strings.CS.remove(configuredUrlPrefix, AUTO_DETECTION));
67
68 if (adaptable instanceof SlingHttpServletRequest) {
69 SlingHttpServletRequest request = (SlingHttpServletRequest)adaptable;
70 urlPrefix = detectFromForwardedHeader(request);
71 if (urlPrefix == null) {
72 urlPrefix = detectFromServletRequest(request);
73 }
74 }
75 }
76 return urlPrefix;
77 }
78
79
80
81
82
83
84 private static @Nullable String detectFromForwardedHeader(@NotNull SlingHttpServletRequest request) {
85
86
87 if (log.isTraceEnabled()) {
88 StringBuilder output = new StringBuilder();
89 Enumeration<String> headers = request.getHeaderNames();
90 while (headers.hasMoreElements()) {
91 String header = headers.nextElement();
92 if (output.length() > 0) {
93 output.append("; ");
94 }
95 output.append(header).append('=').append(request.getHeader(header));
96 }
97 log.trace("HTTP headers: {}", output);
98 }
99
100
101 String forwardedHost = request.getHeader(HTTP_HEADER_X_FORWARDED_HOST);
102 String forwardedProto = request.getHeader(HTTP_HEADER_X_FORWARDED_PROTO);
103 if (StringUtils.isNotEmpty(forwardedHost) && StringUtils.isNotEmpty(forwardedProto)) {
104 return forwardedProto + "://" + forwardedHost;
105 }
106
107
108 String host = request.getHeader(HTTP_HEADER_HOST);
109 String forwardedSsl = request.getHeader(HTTP_HEADER_X_FORWARDED_SSL);
110 if (StringUtils.isNotEmpty(host) && Strings.CI.equals(forwardedSsl, VALUE_ON)) {
111 return "https://" + host;
112 }
113
114 return null;
115 }
116
117 private static @NotNull String detectFromServletRequest(@NotNull SlingHttpServletRequest request) {
118 StringBuilder urlPrefix = new StringBuilder();
119 urlPrefix.append(request.getScheme()).append("://").append(request.getServerName());
120 int port = request.getServerPort();
121 if ((request.isSecure() && port != 443) || (!request.isSecure() && port != 80)) {
122 urlPrefix.append(':').append(Integer.toString(port));
123 }
124 return urlPrefix.toString();
125 }
126
127 }