001/* 002 * Licensed to the Apache Software Foundation (ASF) under one or more 003 * contributor license agreements. See the NOTICE file distributed with 004 * this work for additional information regarding copyright ownership. 005 * The ASF licenses this file to You under the Apache License, Version 2.0 006 * (the "License"); you may not use this file except in compliance with 007 * the License. You may obtain a copy of the License at 008 * 009 * http://www.apache.org/licenses/LICENSE-2.0 010 * 011 * Unless required by applicable law or agreed to in writing, software 012 * distributed under the License is distributed on an "AS IS" BASIS, 013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 014 * See the License for the specific language governing permissions and 015 * limitations under the License. 016 */ 017package org.apache.commons.vfs2.provider.http5; 018 019import java.io.Closeable; 020import java.net.URI; 021import java.util.Collection; 022 023import org.apache.commons.io.function.Uncheck; 024import org.apache.commons.vfs2.Capability; 025import org.apache.commons.vfs2.FileName; 026import org.apache.commons.vfs2.FileObject; 027import org.apache.commons.vfs2.FileSystemOptions; 028import org.apache.commons.vfs2.provider.AbstractFileName; 029import org.apache.commons.vfs2.provider.AbstractFileSystem; 030import org.apache.hc.client5.http.classic.HttpClient; 031import org.apache.hc.client5.http.protocol.HttpClientContext; 032 033/** 034 * http5 file system. 035 * 036 * @since 2.5.0 037 */ 038public class Http5FileSystem extends AbstractFileSystem { 039 040 /** 041 * Internal base URI of this file system. 042 */ 043 private final URI internalBaseURI; 044 045 /** 046 * Internal {@code HttpClient} instance of this file system. 047 */ 048 private final HttpClient httpClient; 049 050 /** 051 * Internal {@code HttpClientContext} instance of this file system. 052 */ 053 private final HttpClientContext httpClientContext; 054 055 /** 056 * Constructs {@code Http4FileSystem}. 057 * 058 * @param rootName root base name 059 * @param fileSystemOptions file system options 060 * @param httpClient {@link HttpClient} instance 061 * @param httpClientContext {@link HttpClientContext} instance 062 */ 063 protected Http5FileSystem(final FileName rootName, final FileSystemOptions fileSystemOptions, final HttpClient httpClient, 064 final HttpClientContext httpClientContext) { 065 super(rootName, null, fileSystemOptions); 066 067 final String rootURI = getRootURI(); 068 final int offset = rootURI.indexOf(':'); 069 final char lastCharOfScheme = offset > 0 ? rootURI.charAt(offset - 1) : 0; 070 071 // if scheme is 'http*s' or 'HTTP*S', then the internal base URI should be 'https'. 'http' otherwise. 072 final String scheme = lastCharOfScheme == 's' || lastCharOfScheme == 'S' ? "https" : "http"; 073 internalBaseURI = URI.create(scheme + rootURI.substring(offset)); 074 this.httpClient = httpClient; 075 this.httpClientContext = httpClientContext; 076 } 077 078 @Override 079 protected void addCapabilities(final Collection<Capability> caps) { 080 caps.addAll(Http5FileProvider.CAPABILITIES); 081 } 082 083 @Override 084 protected FileObject createFile(final AbstractFileName name) throws Exception { 085 return new Http5FileObject<>(name, this); 086 } 087 088 @Override 089 protected void doCloseCommunicationLink() { 090 if (httpClient instanceof Closeable) { 091 // TODO "Error closing HttpClient" Commons IO 092 // Uncheck.run(() -> ((Closeable) httpClient).close(), () -> "Error closing HttpClient"); 093 Uncheck.run(() -> ((Closeable) httpClient).close()); 094 } 095 } 096 097 /** 098 * Gets the internal {@link HttpClient} instance. 099 * 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}