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