View Javadoc
1   /*
2    * Copyright 2012-2025 CodeLibs Project and the Others.
3    *
4    * Licensed under the Apache License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    *
8    *     http://www.apache.org/licenses/LICENSE-2.0
9    *
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
13   * either express or implied. See the License for the specific language
14   * governing permissions and limitations under the License.
15   */
16  package org.codelibs.fess.helper;
17  
18  import static org.codelibs.core.stream.StreamUtil.stream;
19  
20  import java.util.function.Function;
21  
22  import org.codelibs.core.lang.StringUtil;
23  import org.codelibs.core.misc.Tuple3;
24  import org.codelibs.fess.mylasta.direction.FessConfig;
25  import org.codelibs.fess.util.ComponentUtil;
26  import org.lastaflute.web.response.next.HtmlNext;
27  import org.lastaflute.web.util.LaRequestUtil;
28  
29  /**
30   * Helper class for managing virtual host configurations and routing.
31   * This class provides functionality to handle virtual host-based routing
32   * and path resolution based on HTTP headers.
33   */
34  public class VirtualHostHelper {
35  
36      /**
37       * Default constructor.
38       */
39      public VirtualHostHelper() {
40          // Default constructor
41      }
42  
43      /**
44       * Gets the virtual host path for the specified HTML page.
45       *
46       * @param page The HTML page to get the virtual host path for
47       * @return The HTML page with updated virtual host path
48       */
49      public HtmlNext getVirtualHostPath(final HtmlNext page) {
50          return processVirtualHost(s -> {
51              final String basePath = getVirtualHostBasePath(s, page);
52              return new HtmlNext(basePath + page.getRoutingPath());
53          }, page);
54      }
55  
56      /**
57       * Gets the base path for virtual host based on the virtual host key and page.
58       *
59       * @param s The virtual host key
60       * @param page The HTML page
61       * @return The base path for the virtual host
62       */
63      protected String getVirtualHostBasePath(final String s, final HtmlNext page) {
64          return StringUtil.isBlank(s) ? StringUtil.EMPTY : "/" + s;
65      }
66  
67      /**
68       * Gets the virtual host key from the current request.
69       * The key is determined by matching HTTP headers against configured virtual hosts.
70       *
71       * @return The virtual host key, or empty string if no match found
72       */
73      public String getVirtualHostKey() {
74          return LaRequestUtil.getOptionalRequest().map(req -> (String) req.getAttribute(FessConfig.VIRTUAL_HOST_VALUE)).orElseGet(() -> {
75              final String value = processVirtualHost(s -> s, StringUtil.EMPTY);
76              LaRequestUtil.getOptionalRequest().ifPresent(req -> req.setAttribute(FessConfig.VIRTUAL_HOST_VALUE, value));
77              return value;
78          });
79      }
80  
81      /**
82       * Processes virtual host configuration by applying a function to the matched virtual host key.
83       *
84       * @param <T> The return type of the function
85       * @param func The function to apply to the virtual host key
86       * @param defaultValue The default value to return if no virtual host matches
87       * @return The result of applying the function, or the default value
88       */
89      protected <T> T processVirtualHost(final Function<String, T> func, final T defaultValue) {
90          final Tuple3<String, String, String>[] vHosts = ComponentUtil.getFessConfig().getVirtualHosts();
91          return LaRequestUtil.getOptionalRequest().map(req -> {
92              for (final Tuple3<String, String, String> host : vHosts) {
93                  final String headerValue = req.getHeader(host.getValue1());
94                  if (host.getValue2().equalsIgnoreCase(headerValue)) {
95                      return func.apply(host.getValue3());
96                  }
97              }
98              return defaultValue;
99          }).orElse(defaultValue);
100     }
101 
102     /**
103      * Gets all configured virtual host paths.
104      *
105      * @return An array of virtual host paths
106      */
107     public String[] getVirtualHostPaths() {
108         return stream(ComponentUtil.getFessConfig().getVirtualHosts())
109                 .get(stream -> stream.map(h -> "/" + h.getValue3()).toArray(n -> new String[n]));
110     }
111 }