LCOV - code coverage report
Current view: top level - httpd - RequireSslFilter.java (source / functions) Hit Total Coverage
Test: _coverage_report.dat Lines: 17 26 65.4 %
Date: 2022-11-19 15:00:39 Functions: 7 9 77.8 %

          Line data    Source code
       1             : // Copyright (C) 2009 The Android Open Source Project
       2             : //
       3             : // Licensed under the Apache License, Version 2.0 (the "License");
       4             : // you may not use this file except in compliance with the License.
       5             : // You may obtain a copy of the License at
       6             : //
       7             : // http://www.apache.org/licenses/LICENSE-2.0
       8             : //
       9             : // Unless required by applicable law or agreed to in writing, software
      10             : // distributed under the License is distributed on an "AS IS" BASIS,
      11             : // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
      12             : // See the License for the specific language governing permissions and
      13             : // limitations under the License.
      14             : 
      15             : package com.google.gerrit.httpd;
      16             : 
      17             : import com.google.gerrit.common.Nullable;
      18             : import com.google.gerrit.server.config.CanonicalWebUrl;
      19             : import com.google.inject.Inject;
      20             : import com.google.inject.Provider;
      21             : import com.google.inject.Singleton;
      22             : import com.google.inject.servlet.ServletModule;
      23             : import java.io.IOException;
      24             : import javax.servlet.Filter;
      25             : import javax.servlet.FilterChain;
      26             : import javax.servlet.FilterConfig;
      27             : import javax.servlet.ServletException;
      28             : import javax.servlet.ServletRequest;
      29             : import javax.servlet.ServletResponse;
      30             : import javax.servlet.http.HttpServletRequest;
      31             : import javax.servlet.http.HttpServletResponse;
      32             : 
      33             : /** Requires the connection to use SSL, redirects if not. */
      34             : @Singleton
      35             : public class RequireSslFilter implements Filter {
      36             :   public static class RequireSslFilterModule extends ServletModule {
      37             :     private final boolean wantSsl;
      38             : 
      39             :     @Inject
      40          99 :     RequireSslFilterModule(@Nullable @CanonicalWebUrl String canonicalUrl) {
      41          99 :       this.wantSsl = canonicalUrl != null && canonicalUrl.startsWith("https:");
      42          99 :     }
      43             : 
      44             :     @Override
      45             :     protected void configureServlets() {
      46          99 :       if (wantSsl) {
      47           1 :         filter("/*").through(RequireSslFilter.class);
      48             :       }
      49          99 :     }
      50             :   }
      51             : 
      52             :   private final Provider<String> urlProvider;
      53             : 
      54             :   @Inject
      55           1 :   RequireSslFilter(@CanonicalWebUrl @Nullable Provider<String> urlProvider) {
      56           1 :     this.urlProvider = urlProvider;
      57           1 :   }
      58             : 
      59             :   @Override
      60           1 :   public void init(FilterConfig filterConfig) {}
      61             : 
      62             :   @Override
      63           1 :   public void destroy() {}
      64             : 
      65             :   @Override
      66             :   public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
      67             :       throws IOException, ServletException {
      68           1 :     final HttpServletRequest req = (HttpServletRequest) request;
      69           1 :     final HttpServletResponse rsp = (HttpServletResponse) response;
      70             : 
      71           1 :     if (isSecure(req)) {
      72           1 :       chain.doFilter(request, response);
      73             : 
      74             :     } else {
      75             :       // If we wanted SSL, but the user didn't come to us over it,
      76             :       // force SSL by issuing a protocol redirect. Try to keep the
      77             :       // name "localhost" in case this is an SSH port tunnel.
      78             :       //
      79             :       final String url;
      80           0 :       if (isLocalHost(req)) {
      81           0 :         url = getLocalHostUrl(req);
      82             :       } else {
      83           0 :         url = urlProvider.get() + req.getServletPath();
      84             :       }
      85           0 :       rsp.setStatus(HttpServletResponse.SC_MOVED_PERMANENTLY);
      86           0 :       rsp.setHeader("Location", url);
      87             :     }
      88           1 :   }
      89             : 
      90             :   @SuppressWarnings("JdkObsolete")
      91             :   private static String getLocalHostUrl(HttpServletRequest req) {
      92           0 :     StringBuffer b = req.getRequestURL();
      93           0 :     b.replace(0, b.indexOf(":"), "https");
      94           0 :     return b.toString();
      95             :   }
      96             : 
      97             :   private static boolean isSecure(HttpServletRequest req) {
      98           1 :     return "https".equals(req.getScheme()) || req.isSecure();
      99             :   }
     100             : 
     101             :   private static boolean isLocalHost(HttpServletRequest req) {
     102           0 :     return "localhost".equals(req.getServerName()) || "127.0.0.1".equals(req.getServerName());
     103             :   }
     104             : }

Generated by: LCOV version 1.16+git.20220603.dfeb750