View Javadoc
1   /*
2    * ====================================================================
3    * Licensed to the Apache Software Foundation (ASF) under one
4    * or more contributor license agreements.  See the NOTICE file
5    * distributed with this work for additional information
6    * regarding copyright ownership.  The ASF licenses this file
7    * to you under the Apache License, Version 2.0 (the
8    * "License"); you may not use this file except in compliance
9    * with the License.  You may obtain a copy of the License at
10   *
11   *   http://www.apache.org/licenses/LICENSE-2.0
12   *
13   * Unless required by applicable law or agreed to in writing,
14   * software distributed under the License is distributed on an
15   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16   * KIND, either express or implied.  See the License for the
17   * specific language governing permissions and limitations
18   * under the License.
19   * ====================================================================
20   *
21   * This software consists of voluntary contributions made by many
22   * individuals on behalf of the Apache Software Foundation.  For more
23   * information on the Apache Software Foundation, please see
24   * <http://www.apache.org/>.
25   *
26   */
27  package org.apache.hc.client5.http.impl.cache;
28  
29  import java.net.URI;
30  import java.net.URISyntaxException;
31  
32  import org.apache.hc.client5.http.utils.URIUtils;
33  import org.apache.hc.core5.http.HttpHost;
34  import org.apache.hc.core5.http.HttpRequest;
35  import org.apache.hc.core5.http.URIScheme;
36  import org.apache.hc.core5.net.URIAuthority;
37  import org.apache.hc.core5.net.URIBuilder;
38  import org.apache.hc.core5.util.Args;
39  
40  /**
41   * HTTP cache support utilities.
42   *
43   * @since 5.0
44   */
45  public final class HttpCacheSupport {
46  
47      private static final URI BASE_URI = URI.create("http://example.com/");
48  
49      /**
50       * Returns text representation of the request URI of the given {@link HttpRequest}.
51       * This method will use {@link HttpRequest#getPath()}, {@link HttpRequest#getScheme()} and
52       * {@link HttpRequest#getAuthority()} values when available or attributes of target
53       * {@link HttpHost } in order to construct an absolute URI.
54       * <p>
55       * This method will not attempt to ensure validity of the resultant text representation.
56       *
57       * @param request the {@link HttpRequest}
58       * @param target target host
59       *
60       * @return String the request URI
61       */
62      public static String getRequestUri(final HttpRequest request, final HttpHost target) {
63          Args.notNull(request, "HTTP request");
64          Args.notNull(target, "Target");
65          final StringBuilder buf = new StringBuilder();
66          final URIAuthority authority = request.getAuthority();
67          if (authority != null) {
68              final String scheme = request.getScheme();
69              buf.append(scheme != null ? scheme : URIScheme.HTTP.id).append("://");
70              buf.append(authority.getHostName());
71              if (authority.getPort() >= 0) {
72                  buf.append(":").append(authority.getPort());
73              }
74          } else {
75              buf.append(target.getSchemeName()).append("://");
76              buf.append(target.getHostName());
77              if (target.getPort() >= 0) {
78                  buf.append(":").append(target.getPort());
79              }
80          }
81          final String path = request.getPath();
82          if (path == null) {
83              buf.append("/");
84          } else {
85              if (buf.length() > 0 && !path.startsWith("/")) {
86                  buf.append("/");
87              }
88              buf.append(path);
89          }
90          return buf.toString();
91      }
92  
93      /**
94       * Returns normalized representation of the request URI optimized for use as a cache key.
95       * This method ensures the resultant URI has an explicit port in the authority component,
96       * and explicit path component and no fragment.
97       *
98       * @param requestUri original request URI
99       * @return normalized URI.
100      * @throws URISyntaxException
101      */
102     public static URI normalize(final URI requestUri) throws URISyntaxException {
103         Args.notNull(requestUri, "URI");
104         final URIBuilder builder = new URIBuilder(requestUri.isAbsolute() ? URIUtils.resolve(BASE_URI, requestUri) : requestUri) ;
105         if (builder.getHost() != null) {
106             if (builder.getScheme() == null) {
107                 builder.setScheme(URIScheme.HTTP.id);
108             }
109             if (builder.getPort() <= -1) {
110                 if (URIScheme.HTTP.same(builder.getScheme())) {
111                     builder.setPort(80);
112                 } else if (URIScheme.HTTPS.same(builder.getScheme())) {
113                     builder.setPort(443);
114                 }
115             }
116         }
117         builder.setFragment(null);
118         if (builder.isPathEmpty()) {
119             builder.setPathSegments("");
120         }
121         return builder.build();
122     }
123 
124     /**
125      * Lenient URI parser that normalizes valid {@link URI}s and returns {@code null} for malformed URIs.
126      * @deprecated Use {@link #normalizeQuietly(String)}
127      */
128     @Deprecated
129     public static URI normalizeQuetly(final String requestUri) {
130         if (requestUri == null) {
131             return null;
132         }
133         try {
134             return normalize(new URI(requestUri));
135         } catch (final URISyntaxException ex) {
136             return null;
137         }
138     }
139 
140     /**
141      * Lenient URI parser that normalizes valid {@link URI}s and returns {@code null} for malformed URIs.
142      * @since 5.2
143      */
144     public static URI normalizeQuietly(final String requestUri) {
145         if (requestUri == null) {
146             return null;
147         }
148         try {
149             return normalize(new URI(requestUri));
150         } catch (final URISyntaxException ex) {
151             return null;
152         }
153     }
154 
155 }