1 /*
2 * Licensed to the Apache Software Foundation (ASF) under one or more
3 * contributor license agreements. See the NOTICE file distributed with
4 * this work for additional information regarding copyright ownership.
5 * The ASF licenses this file to You under the Apache License, Version 2.0
6 * (the "License"); you may not use this file except in compliance with
7 * the License. You may obtain a copy of the License at
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 */
17 package org.apache.commons.vfs2.provider.http5;
18
19 import java.io.Closeable;
20 import java.net.URI;
21 import java.util.Collection;
22
23 import org.apache.commons.io.function.Uncheck;
24 import org.apache.commons.vfs2.Capability;
25 import org.apache.commons.vfs2.FileName;
26 import org.apache.commons.vfs2.FileObject;
27 import org.apache.commons.vfs2.FileSystemOptions;
28 import org.apache.commons.vfs2.provider.AbstractFileName;
29 import org.apache.commons.vfs2.provider.AbstractFileSystem;
30 import org.apache.hc.client5.http.classic.HttpClient;
31 import org.apache.hc.client5.http.protocol.HttpClientContext;
32
33 /**
34 * http5 file system.
35 *
36 * @since 2.5.0
37 */
38 public class Http5FileSystem extends AbstractFileSystem {
39
40 /**
41 * Internal base URI of this file system.
42 */
43 private final URI internalBaseURI;
44
45 /**
46 * Internal {@code HttpClient} instance of this file system.
47 */
48 private final HttpClient httpClient;
49
50 /**
51 * Internal {@code HttpClientContext} instance of this file system.
52 */
53 private final HttpClientContext httpClientContext;
54
55 /**
56 * Constructs {@code Http4FileSystem}.
57 *
58 * @param rootName root base name
59 * @param fileSystemOptions file system options
60 * @param httpClient {@link HttpClient} instance
61 * @param httpClientContext {@link HttpClientContext} instance
62 */
63 protected Http5FileSystem(final FileName rootName, final FileSystemOptions fileSystemOptions, final HttpClient httpClient,
64 final HttpClientContext httpClientContext) {
65 super(rootName, null, fileSystemOptions);
66
67 final String rootURI = getRootURI();
68 final int offset = rootURI.indexOf(':');
69 final char lastCharOfScheme = offset > 0 ? rootURI.charAt(offset - 1) : 0;
70
71 // if scheme is 'http*s' or 'HTTP*S', then the internal base URI should be 'https'. 'http' otherwise.
72 final String scheme = lastCharOfScheme == 's' || lastCharOfScheme == 'S' ? "https" : "http";
73 internalBaseURI = URI.create(scheme + rootURI.substring(offset));
74 this.httpClient = httpClient;
75 this.httpClientContext = httpClientContext;
76 }
77
78 @Override
79 protected void addCapabilities(final Collection<Capability> caps) {
80 caps.addAll(Http5FileProvider.CAPABILITIES);
81 }
82
83 @Override
84 protected FileObject createFile(final AbstractFileName name) throws Exception {
85 return new Http5FileObject<>(name, this);
86 }
87
88 @Override
89 protected void doCloseCommunicationLink() {
90 if (httpClient instanceof Closeable) {
91 // TODO "Error closing HttpClient" Commons IO
92 // Uncheck.run(() -> ((Closeable) httpClient).close(), () -> "Error closing HttpClient");
93 Uncheck.run(() -> ((Closeable) httpClient).close());
94 }
95 }
96
97 /**
98 * Gets the internal {@link HttpClient} instance.
99 *
100 * @return the internal {@link HttpClient} instance
101 */
102 protected HttpClient getHttpClient() {
103 return httpClient;
104 }
105
106 /**
107 * Gets the internal {@link HttpClientContext} instance.
108 *
109 * @return the internal {@link HttpClientContext} instance
110 */
111 protected HttpClientContext getHttpClientContext() {
112 return httpClientContext;
113 }
114
115 /**
116 * Gets the internal base {@code URI} instance.
117 *
118 * @return the internal base {@code URI} instance
119 */
120 protected URI getInternalBaseURI() {
121 return internalBaseURI;
122 }
123 }