You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@commons.apache.org by gg...@apache.org on 2018/11/02 01:53:30 UTC
svn commit: r1845527 [1/2] - in /commons/proper/vfs/trunk: ./
commons-vfs2-examples/
commons-vfs2-examples/src/main/java/org/apache/commons/vfs2/example/
commons-vfs2-sandbox/ commons-vfs2/
commons-vfs2/src/main/java/org/apache/commons/vfs2/provider/ c...
Author: ggregory
Date: Fri Nov 2 01:53:29 2018
New Revision: 1845527
URL: http://svn.apache.org/viewvc?rev=1845527&view=rev
Log:
[VFS-360] Migrate to HttpComponent HttpClient. This patch from Woonsan Ko (woonsan on GitHub) adds a new provider "http4" using Apache HttpComponents HttpClient 4. PR https://github.com/apache/commons-vfs/pull/38. Closes #38.
Added:
commons/proper/vfs/trunk/commons-vfs2-examples/README.md
commons/proper/vfs/trunk/commons-vfs2/src/main/java/org/apache/commons/vfs2/provider/GenericURLFileName.java
commons/proper/vfs/trunk/commons-vfs2/src/main/java/org/apache/commons/vfs2/provider/GenericURLFileNameParser.java
commons/proper/vfs/trunk/commons-vfs2/src/main/java/org/apache/commons/vfs2/provider/http4/
commons/proper/vfs/trunk/commons-vfs2/src/main/java/org/apache/commons/vfs2/provider/http4/Http4FileContentInfoFactory.java
commons/proper/vfs/trunk/commons-vfs2/src/main/java/org/apache/commons/vfs2/provider/http4/Http4FileNameParser.java
commons/proper/vfs/trunk/commons-vfs2/src/main/java/org/apache/commons/vfs2/provider/http4/Http4FileObject.java
commons/proper/vfs/trunk/commons-vfs2/src/main/java/org/apache/commons/vfs2/provider/http4/Http4FileProvider.java
commons/proper/vfs/trunk/commons-vfs2/src/main/java/org/apache/commons/vfs2/provider/http4/Http4FileSystem.java
commons/proper/vfs/trunk/commons-vfs2/src/main/java/org/apache/commons/vfs2/provider/http4/Http4FileSystemConfigBuilder.java
commons/proper/vfs/trunk/commons-vfs2/src/main/java/org/apache/commons/vfs2/provider/http4/Http4RandomAccessContent.java
commons/proper/vfs/trunk/commons-vfs2/src/main/java/org/apache/commons/vfs2/provider/http4/MonitoredHttpResponseContentInputStream.java
commons/proper/vfs/trunk/commons-vfs2/src/main/java/org/apache/commons/vfs2/provider/http4/package.html
commons/proper/vfs/trunk/commons-vfs2/src/main/java/org/apache/commons/vfs2/provider/http4s/
commons/proper/vfs/trunk/commons-vfs2/src/main/java/org/apache/commons/vfs2/provider/http4s/Http4sFileNameParser.java
commons/proper/vfs/trunk/commons-vfs2/src/main/java/org/apache/commons/vfs2/provider/http4s/Http4sFileProvider.java
commons/proper/vfs/trunk/commons-vfs2/src/main/java/org/apache/commons/vfs2/provider/http4s/package.html
commons/proper/vfs/trunk/commons-vfs2/src/main/java/org/apache/commons/vfs2/util/URIBitSets.java
commons/proper/vfs/trunk/commons-vfs2/src/main/java/org/apache/commons/vfs2/util/URIUtils.java
commons/proper/vfs/trunk/commons-vfs2/src/test/java/org/apache/commons/vfs2/provider/http4/
commons/proper/vfs/trunk/commons-vfs2/src/test/java/org/apache/commons/vfs2/provider/http4/test/
commons/proper/vfs/trunk/commons-vfs2/src/test/java/org/apache/commons/vfs2/provider/http4/test/Http4FilesCacheTestCase.java
commons/proper/vfs/trunk/commons-vfs2/src/test/java/org/apache/commons/vfs2/provider/http4/test/Http4GetContentInfoTest.java
commons/proper/vfs/trunk/commons-vfs2/src/test/java/org/apache/commons/vfs2/provider/http4/test/Http4ProviderTestCase.java
commons/proper/vfs/trunk/commons-vfs2/src/test/java/org/apache/commons/vfs2/provider/http4s/
commons/proper/vfs/trunk/commons-vfs2/src/test/java/org/apache/commons/vfs2/provider/http4s/test/
commons/proper/vfs/trunk/commons-vfs2/src/test/java/org/apache/commons/vfs2/provider/http4s/test/Http4sGetContentInfoTest.java
Modified:
commons/proper/vfs/trunk/commons-vfs2-examples/pom.xml
commons/proper/vfs/trunk/commons-vfs2-examples/src/main/java/org/apache/commons/vfs2/example/Shell.java
commons/proper/vfs/trunk/commons-vfs2-sandbox/pom.xml
commons/proper/vfs/trunk/commons-vfs2/pom.xml
commons/proper/vfs/trunk/commons-vfs2/src/main/java/org/apache/commons/vfs2/provider/URLFileName.java
commons/proper/vfs/trunk/commons-vfs2/src/main/java/org/apache/commons/vfs2/provider/URLFileNameParser.java
commons/proper/vfs/trunk/commons-vfs2/src/main/java/org/apache/commons/vfs2/provider/url/UrlFileProvider.java
commons/proper/vfs/trunk/commons-vfs2/src/test/java/org/apache/commons/vfs2/provider/DefaultFileContentTest.java
commons/proper/vfs/trunk/pom.xml
Added: commons/proper/vfs/trunk/commons-vfs2-examples/README.md
URL: http://svn.apache.org/viewvc/commons/proper/vfs/trunk/commons-vfs2-examples/README.md?rev=1845527&view=auto
==============================================================================
--- commons/proper/vfs/trunk/commons-vfs2-examples/README.md (added)
+++ commons/proper/vfs/trunk/commons-vfs2-examples/README.md Fri Nov 2 01:53:29 2018
@@ -0,0 +1,35 @@
+<!---
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+# Test Provider(s) with the Shell
+
+## Build modules in the parent folder
+
+ mvn clean install
+
+## Test `http` and `https` providers
+
+ mvn -Pshell -Dhttp
+
+## Test `http4` and `http4s` providers
+
+ mvn -Pshell -Dhttp4
+
+## Test `http`, `https`, `http4` and `http4s` providers together
+
+ mvn -Pshell -Dhttp -Dhttp4
+
Modified: commons/proper/vfs/trunk/commons-vfs2-examples/pom.xml
URL: http://svn.apache.org/viewvc/commons/proper/vfs/trunk/commons-vfs2-examples/pom.xml?rev=1845527&r1=1845526&r2=1845527&view=diff
==============================================================================
--- commons/proper/vfs/trunk/commons-vfs2-examples/pom.xml (original)
+++ commons/proper/vfs/trunk/commons-vfs2-examples/pom.xml Fri Nov 2 01:53:29 2018
@@ -51,11 +51,6 @@
<optional>true</optional>
</dependency>
<dependency>
- <groupId>commons-httpclient</groupId>
- <artifactId>commons-httpclient</artifactId>
- <optional>true</optional>
- </dependency>
- <dependency>
<groupId>com.jcraft</groupId>
<artifactId>jsch</artifactId>
<optional>true</optional>
@@ -79,4 +74,67 @@
</resources>
</build>
+ <profiles>
+
+ <profile>
+ <id>shell</id>
+ <build>
+ <defaultGoal>validate</defaultGoal>
+ <plugins>
+ <plugin>
+ <groupId>org.codehaus.mojo</groupId>
+ <artifactId>exec-maven-plugin</artifactId>
+ <version>1.6.0</version>
+ <executions>
+ <execution>
+ <phase>validate</phase>
+ <goals>
+ <goal>java</goal>
+ </goals>
+ </execution>
+ </executions>
+ <configuration>
+ <mainClass>org.apache.commons.vfs2.example.Shell</mainClass>
+ </configuration>
+ </plugin>
+ </plugins>
+ </build>
+ </profile>
+
+ <profile>
+ <id>with-http</id>
+ <activation>
+ <activeByDefault>true</activeByDefault>
+ <property>
+ <name>http</name>
+ </property>
+ </activation>
+ <dependencies>
+ <dependency>
+ <groupId>commons-httpclient</groupId>
+ <artifactId>commons-httpclient</artifactId>
+ <scope>runtime</scope>
+ </dependency>
+ </dependencies>
+ </profile>
+
+ <profile>
+ <id>with-http4</id>
+ <activation>
+ <activeByDefault>true</activeByDefault>
+ <property>
+ <name>http4</name>
+ </property>
+ </activation>
+ <dependencies>
+ <dependency>
+ <groupId>org.apache.httpcomponents</groupId>
+ <artifactId>httpclient</artifactId>
+ <scope>runtime</scope>
+ </dependency>
+ </dependencies>
+ </profile>
+
+ </profiles>
+
</project>
Modified: commons/proper/vfs/trunk/commons-vfs2-examples/src/main/java/org/apache/commons/vfs2/example/Shell.java
URL: http://svn.apache.org/viewvc/commons/proper/vfs/trunk/commons-vfs2-examples/src/main/java/org/apache/commons/vfs2/example/Shell.java?rev=1845527&r1=1845526&r2=1845527&view=diff
==============================================================================
--- commons/proper/vfs/trunk/commons-vfs2-examples/src/main/java/org/apache/commons/vfs2/example/Shell.java (original)
+++ commons/proper/vfs/trunk/commons-vfs2-examples/src/main/java/org/apache/commons/vfs2/example/Shell.java Fri Nov 2 01:53:29 2018
@@ -38,7 +38,9 @@ import org.apache.commons.vfs2.FileType;
import org.apache.commons.vfs2.FileUtil;
import org.apache.commons.vfs2.Selectors;
import org.apache.commons.vfs2.VFS;
+import org.apache.commons.vfs2.impl.DefaultFileSystemManager;
import org.apache.commons.vfs2.operations.FileOperationProvider;
+import org.apache.commons.vfs2.provider.FileProvider;
/**
* A simple command-line shell for performing file operations.
@@ -46,12 +48,30 @@ import org.apache.commons.vfs2.operation
* See <a href="https://wiki.apache.org/commons/VfsExampleShell">Commons VFS Shell Examples</a> in Apache Commons Wiki.
*/
public final class Shell {
+
private final FileSystemManager mgr;
private FileObject cwd;
private final BufferedReader reader;
private Shell() throws IOException {
mgr = VFS.getManager();
+
+ // TODO: VFS-360 - Remove this manual registration of http4 once http4 becomes part of standard providers.
+ boolean httpClient4Available = false;
+ try {
+ Class.forName("org.apache.http.client.HttpClient");
+ httpClient4Available = true;
+ final DefaultFileSystemManager manager = (DefaultFileSystemManager) VFS.getManager();
+ if (!manager.hasProvider("http4")) {
+ manager.addProvider("http4", (FileProvider) Class.forName("org.apache.commons.vfs2.provider.http4.Http4FileProvider").newInstance());
+ manager.addProvider("http4s", (FileProvider) Class.forName("org.apache.commons.vfs2.provider.http4s.Http4sFileProvider").newInstance());
+ }
+ } catch (Exception e) {
+ if (httpClient4Available) {
+ e.printStackTrace();
+ }
+ }
+
cwd = mgr.toFileObject(new File(System.getProperty("user.dir")));
reader = new BufferedReader(new InputStreamReader(System.in, Charset.defaultCharset()));
}
Modified: commons/proper/vfs/trunk/commons-vfs2-sandbox/pom.xml
URL: http://svn.apache.org/viewvc/commons/proper/vfs/trunk/commons-vfs2-sandbox/pom.xml?rev=1845527&r1=1845526&r2=1845527&view=diff
==============================================================================
--- commons/proper/vfs/trunk/commons-vfs2-sandbox/pom.xml (original)
+++ commons/proper/vfs/trunk/commons-vfs2-sandbox/pom.xml Fri Nov 2 01:53:29 2018
@@ -55,6 +55,11 @@
<optional>true</optional>
</dependency>
<dependency>
+ <groupId>org.apache.httpcomponents</groupId>
+ <artifactId>httpclient</artifactId>
+ <optional>true</optional>
+ </dependency>
+ <dependency>
<groupId>javax.mail</groupId>
<artifactId>mail</artifactId>
<optional>true</optional>
Modified: commons/proper/vfs/trunk/commons-vfs2/pom.xml
URL: http://svn.apache.org/viewvc/commons/proper/vfs/trunk/commons-vfs2/pom.xml?rev=1845527&r1=1845526&r2=1845527&view=diff
==============================================================================
--- commons/proper/vfs/trunk/commons-vfs2/pom.xml (original)
+++ commons/proper/vfs/trunk/commons-vfs2/pom.xml Fri Nov 2 01:53:29 2018
@@ -75,6 +75,11 @@
<optional>true</optional>
</dependency>
<dependency>
+ <groupId>org.apache.httpcomponents</groupId>
+ <artifactId>httpclient</artifactId>
+ <optional>true</optional>
+ </dependency>
+ <dependency>
<groupId>org.apache.jackrabbit</groupId>
<artifactId>jackrabbit-webdav</artifactId>
<optional>true</optional>
Added: commons/proper/vfs/trunk/commons-vfs2/src/main/java/org/apache/commons/vfs2/provider/GenericURLFileName.java
URL: http://svn.apache.org/viewvc/commons/proper/vfs/trunk/commons-vfs2/src/main/java/org/apache/commons/vfs2/provider/GenericURLFileName.java?rev=1845527&view=auto
==============================================================================
--- commons/proper/vfs/trunk/commons-vfs2/src/main/java/org/apache/commons/vfs2/provider/GenericURLFileName.java (added)
+++ commons/proper/vfs/trunk/commons-vfs2/src/main/java/org/apache/commons/vfs2/provider/GenericURLFileName.java Fri Nov 2 01:53:29 2018
@@ -0,0 +1,139 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.commons.vfs2.provider;
+
+import java.net.URISyntaxException;
+
+import org.apache.commons.vfs2.FileName;
+import org.apache.commons.vfs2.FileSystemException;
+import org.apache.commons.vfs2.FileType;
+import org.apache.commons.vfs2.util.URIUtils;
+
+/**
+ * Generic file name that represents a URL.
+ */
+public class GenericURLFileName extends GenericFileName {
+
+ private static final int BUFFER_SIZE = 250;
+
+ private final String queryString;
+
+ public GenericURLFileName(final String scheme, final String hostName, final int port, final int defaultPort,
+ final String userName, final String password, final String path, final FileType type,
+ final String queryString) {
+ super(scheme, hostName, port, defaultPort, userName, password, path, type);
+ this.queryString = queryString;
+ }
+
+ /**
+ * Get the query string.
+ *
+ * @return the query string part of the filename
+ */
+ public String getQueryString() {
+ return queryString;
+ }
+
+ /**
+ * Get the path and query string e.g. /path/servlet?param1=true.
+ *
+ * @return the path and its query string
+ */
+ public String getPathQuery() {
+ final StringBuilder sb = new StringBuilder(BUFFER_SIZE);
+ sb.append(getPath());
+ sb.append("?");
+ sb.append(getQueryString());
+
+ return sb.toString();
+ }
+
+ /**
+ * Get the path encoded suitable for url like filesystem e.g. (http, webdav).
+ *
+ * @param charset the charset used for the path encoding
+ * @return The encoded path.
+ * @throws URISyntaxException If an error occurs encoding the URI.
+ * @throws FileSystemException If some other error occurs.
+ */
+ public String getPathQueryEncoded(final String charset) throws URISyntaxException, FileSystemException {
+ if (getQueryString() == null) {
+ if (charset != null) {
+ return URIUtils.encodePath(getPathDecoded(), charset);
+ } else {
+ return URIUtils.encodePath(getPathDecoded());
+ }
+ }
+
+ final StringBuilder sb = new StringBuilder(BUFFER_SIZE);
+ if (charset != null) {
+ sb.append(URIUtils.encodePath(getPathDecoded(), charset));
+ } else {
+ sb.append(URIUtils.encodePath(getPathDecoded()));
+ }
+ sb.append("?");
+ sb.append(getQueryString());
+ return sb.toString();
+ }
+
+ /**
+ * Create a FileName.
+ *
+ * @param absPath The absolute path.
+ * @param type The FileType.
+ * @return The FileName
+ */
+ @Override
+ public FileName createName(final String absPath, final FileType type) {
+ return new GenericURLFileName(getScheme(), getHostName(), getPort(), getDefaultPort(), getUserName(), getPassword(),
+ absPath, type, getQueryString());
+ }
+
+ /**
+ * Append query string to the uri.
+ *
+ * @return the uri
+ */
+ @Override
+ protected String createURI() {
+ if (getQueryString() != null) {
+ final StringBuilder sb = new StringBuilder(BUFFER_SIZE);
+ sb.append(super.createURI());
+ sb.append("?");
+ sb.append(getQueryString());
+
+ return sb.toString();
+ }
+
+ return super.createURI();
+ }
+
+ /**
+ * Encode a URI.
+ *
+ * @param charset The character set.
+ * @return The encoded URI
+ * @throws FileSystemException if some other exception occurs.
+ * @throws URISyntaxException if an exception occurs encoding the URI.
+ */
+ public String getURIEncoded(final String charset) throws FileSystemException, URISyntaxException {
+ final StringBuilder sb = new StringBuilder(BUFFER_SIZE);
+ appendRootUri(sb, true);
+ sb.append(getPathQueryEncoded(charset));
+ return sb.toString();
+ }
+}
Added: commons/proper/vfs/trunk/commons-vfs2/src/main/java/org/apache/commons/vfs2/provider/GenericURLFileNameParser.java
URL: http://svn.apache.org/viewvc/commons/proper/vfs/trunk/commons-vfs2/src/main/java/org/apache/commons/vfs2/provider/GenericURLFileNameParser.java?rev=1845527&view=auto
==============================================================================
--- commons/proper/vfs/trunk/commons-vfs2/src/main/java/org/apache/commons/vfs2/provider/GenericURLFileNameParser.java (added)
+++ commons/proper/vfs/trunk/commons-vfs2/src/main/java/org/apache/commons/vfs2/provider/GenericURLFileNameParser.java Fri Nov 2 01:53:29 2018
@@ -0,0 +1,60 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.commons.vfs2.provider;
+
+import org.apache.commons.vfs2.FileName;
+import org.apache.commons.vfs2.FileSystemException;
+import org.apache.commons.vfs2.FileType;
+
+/**
+ * Generic implementation for any url based filesystem, without depending a specific library.
+ * <p>
+ * Parses the url into user/password/host/port/path/queryString.
+ */
+public class GenericURLFileNameParser extends HostFileNameParser {
+
+ public GenericURLFileNameParser(final int defaultPort) {
+ super(defaultPort);
+ }
+
+ @Override
+ public boolean encodeCharacter(final char ch) {
+ return super.encodeCharacter(ch) || ch == '?';
+ }
+
+ @Override
+ public FileName parseUri(final VfsComponentContext context, final FileName base, final String filename)
+ throws FileSystemException {
+ // FTP URI are generic URI (as per RFC 2396)
+ final StringBuilder name = new StringBuilder();
+
+ // Extract the scheme and authority parts
+ final Authority auth = extractToPath(filename, name);
+
+ // Extract the queryString
+ final String queryString = UriParser.extractQueryString(name);
+
+ // Decode and normalise the file name
+ UriParser.canonicalizePath(name, 0, name.length(), this);
+ UriParser.fixSeparators(name);
+ final FileType fileType = UriParser.normalisePath(name);
+ final String path = name.toString();
+
+ return new GenericURLFileName(auth.getScheme(), auth.getHostName(), auth.getPort(), getDefaultPort(),
+ auth.getUserName(), auth.getPassword(), path, fileType, queryString);
+ }
+}
Modified: commons/proper/vfs/trunk/commons-vfs2/src/main/java/org/apache/commons/vfs2/provider/URLFileName.java
URL: http://svn.apache.org/viewvc/commons/proper/vfs/trunk/commons-vfs2/src/main/java/org/apache/commons/vfs2/provider/URLFileName.java?rev=1845527&r1=1845526&r2=1845527&view=diff
==============================================================================
--- commons/proper/vfs/trunk/commons-vfs2/src/main/java/org/apache/commons/vfs2/provider/URLFileName.java (original)
+++ commons/proper/vfs/trunk/commons-vfs2/src/main/java/org/apache/commons/vfs2/provider/URLFileName.java Fri Nov 2 01:53:29 2018
@@ -24,7 +24,9 @@ import org.apache.commons.vfs2.FileType;
/**
* A file name that represents URL.
+ * @deprecated Use {@link GenericURLFileName} as it doesn't depend on Http Client v3 API directly.
*/
+@Deprecated
public class URLFileName extends GenericFileName {
private static final int BUFFER_SIZE = 250;
Modified: commons/proper/vfs/trunk/commons-vfs2/src/main/java/org/apache/commons/vfs2/provider/URLFileNameParser.java
URL: http://svn.apache.org/viewvc/commons/proper/vfs/trunk/commons-vfs2/src/main/java/org/apache/commons/vfs2/provider/URLFileNameParser.java?rev=1845527&r1=1845526&r2=1845527&view=diff
==============================================================================
--- commons/proper/vfs/trunk/commons-vfs2/src/main/java/org/apache/commons/vfs2/provider/URLFileNameParser.java (original)
+++ commons/proper/vfs/trunk/commons-vfs2/src/main/java/org/apache/commons/vfs2/provider/URLFileNameParser.java Fri Nov 2 01:53:29 2018
@@ -24,7 +24,9 @@ import org.apache.commons.vfs2.FileType;
* Implementation for any url based filesystem.
* <p>
* Parses the url into user/password/host/port/path/queryString.
+ * @deprecated Use {@link GenericURLFileNameParser} as it doesn't depend on Http Client v3 API directly.
*/
+@Deprecated
public class URLFileNameParser extends HostFileNameParser {
public URLFileNameParser(final int defaultPort) {
super(defaultPort);
Added: commons/proper/vfs/trunk/commons-vfs2/src/main/java/org/apache/commons/vfs2/provider/http4/Http4FileContentInfoFactory.java
URL: http://svn.apache.org/viewvc/commons/proper/vfs/trunk/commons-vfs2/src/main/java/org/apache/commons/vfs2/provider/http4/Http4FileContentInfoFactory.java?rev=1845527&view=auto
==============================================================================
--- commons/proper/vfs/trunk/commons-vfs2/src/main/java/org/apache/commons/vfs2/provider/http4/Http4FileContentInfoFactory.java (added)
+++ commons/proper/vfs/trunk/commons-vfs2/src/main/java/org/apache/commons/vfs2/provider/http4/Http4FileContentInfoFactory.java Fri Nov 2 01:53:29 2018
@@ -0,0 +1,63 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.commons.vfs2.provider.http4;
+
+import java.io.IOException;
+
+import org.apache.commons.vfs2.FileContent;
+import org.apache.commons.vfs2.FileContentInfo;
+import org.apache.commons.vfs2.FileContentInfoFactory;
+import org.apache.commons.vfs2.FileSystemException;
+import org.apache.commons.vfs2.impl.DefaultFileContentInfo;
+import org.apache.commons.vfs2.util.FileObjectUtils;
+import org.apache.http.Header;
+import org.apache.http.HttpResponse;
+import org.apache.http.entity.ContentType;
+import org.apache.http.protocol.HTTP;
+
+/**
+ * Creates <code>FileContentInfoFactory</code> instances for http4 provider.
+ */
+public class Http4FileContentInfoFactory implements FileContentInfoFactory {
+
+ @SuppressWarnings("unchecked")
+ @Override
+ public FileContentInfo create(final FileContent fileContent) throws FileSystemException {
+ String contentMimeType = null;
+ String contentCharset = null;
+
+ try (final Http4FileObject<Http4FileSystem> http4File = (Http4FileObject<Http4FileSystem>) FileObjectUtils
+ .getAbstractFileObject(fileContent.getFile())) {
+ final HttpResponse lastHeadResponse = http4File.getLastHeadResponse();
+
+ final Header header = lastHeadResponse.getFirstHeader(HTTP.CONTENT_TYPE);
+
+ if (header != null) {
+ final ContentType contentType = ContentType.parse(header.getValue());
+ contentMimeType = contentType.getMimeType();
+
+ if (contentType.getCharset() != null) {
+ contentCharset = contentType.getCharset().name();
+ }
+ }
+
+ return new DefaultFileContentInfo(contentMimeType, contentCharset);
+ } catch (final IOException e) {
+ throw new FileSystemException(e);
+ }
+ }
+}
Added: commons/proper/vfs/trunk/commons-vfs2/src/main/java/org/apache/commons/vfs2/provider/http4/Http4FileNameParser.java
URL: http://svn.apache.org/viewvc/commons/proper/vfs/trunk/commons-vfs2/src/main/java/org/apache/commons/vfs2/provider/http4/Http4FileNameParser.java?rev=1845527&view=auto
==============================================================================
--- commons/proper/vfs/trunk/commons-vfs2/src/main/java/org/apache/commons/vfs2/provider/http4/Http4FileNameParser.java (added)
+++ commons/proper/vfs/trunk/commons-vfs2/src/main/java/org/apache/commons/vfs2/provider/http4/Http4FileNameParser.java Fri Nov 2 01:53:29 2018
@@ -0,0 +1,38 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.commons.vfs2.provider.http4;
+
+import org.apache.commons.vfs2.provider.FileNameParser;
+import org.apache.commons.vfs2.provider.GenericURLFileNameParser;
+
+/**
+ * <code>FileNameParser</code> implementation for http4 provider, setting default port to 80.
+ */
+public class Http4FileNameParser extends GenericURLFileNameParser {
+
+ private static final int DEFAULT_PORT = 80;
+
+ private static final Http4FileNameParser INSTANCE = new Http4FileNameParser();
+
+ public Http4FileNameParser() {
+ super(DEFAULT_PORT);
+ }
+
+ public static FileNameParser getInstance() {
+ return INSTANCE;
+ }
+}
Added: commons/proper/vfs/trunk/commons-vfs2/src/main/java/org/apache/commons/vfs2/provider/http4/Http4FileObject.java
URL: http://svn.apache.org/viewvc/commons/proper/vfs/trunk/commons-vfs2/src/main/java/org/apache/commons/vfs2/provider/http4/Http4FileObject.java?rev=1845527&view=auto
==============================================================================
--- commons/proper/vfs/trunk/commons-vfs2/src/main/java/org/apache/commons/vfs2/provider/http4/Http4FileObject.java (added)
+++ commons/proper/vfs/trunk/commons-vfs2/src/main/java/org/apache/commons/vfs2/provider/http4/Http4FileObject.java Fri Nov 2 01:53:29 2018
@@ -0,0 +1,229 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.commons.vfs2.provider.http4;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.URI;
+import java.net.URISyntaxException;
+
+import org.apache.commons.vfs2.FileContentInfoFactory;
+import org.apache.commons.vfs2.FileNotFoundException;
+import org.apache.commons.vfs2.FileSystemException;
+import org.apache.commons.vfs2.FileSystemOptions;
+import org.apache.commons.vfs2.FileType;
+import org.apache.commons.vfs2.RandomAccessContent;
+import org.apache.commons.vfs2.provider.AbstractFileName;
+import org.apache.commons.vfs2.provider.AbstractFileObject;
+import org.apache.commons.vfs2.provider.GenericURLFileName;
+import org.apache.commons.vfs2.util.RandomAccessMode;
+import org.apache.http.Header;
+import org.apache.http.HttpResponse;
+import org.apache.http.HttpStatus;
+import org.apache.http.client.HttpClient;
+import org.apache.http.client.methods.HttpGet;
+import org.apache.http.client.methods.HttpHead;
+import org.apache.http.client.methods.HttpUriRequest;
+import org.apache.http.client.protocol.HttpClientContext;
+import org.apache.http.client.utils.DateUtils;
+import org.apache.http.client.utils.URIUtils;
+import org.apache.http.protocol.HTTP;
+
+/**
+ * A file object backed by Apache HttpComponents HttpClient.
+ *
+ * @param <FS> An {@link Http4FileSystem} subclass
+ */
+public class Http4FileObject<FS extends Http4FileSystem> extends AbstractFileObject<FS> {
+
+ /**
+ * URL charset string.
+ */
+ private final String urlCharset;
+
+ /**
+ * Internal URI mapped to this <code>FileObject</code>.
+ * For example, the internal URI of <code>http4://example.com/a.txt</code> is <code>http://example.com/a.txt</code>.
+ */
+ private final URI internalURI;
+
+ /**
+ * The last executed HEAD <code>HttpResponse</code> object.
+ */
+ private HttpResponse lastHeadResponse;
+
+ /**
+ * Construct <code>Http4FileObject</code>.
+ * @param name file name
+ * @param fileSystem file system
+ * @throws FileSystemException if any error occurs
+ * @throws URISyntaxException if given file name cannot be converted to a URI due to URI syntax error
+ */
+ protected Http4FileObject(final AbstractFileName name, final FS fileSystem)
+ throws FileSystemException, URISyntaxException {
+ this(name, fileSystem, Http4FileSystemConfigBuilder.getInstance());
+ }
+
+ /**
+ * Construct <code>Http4FileObject</code>.
+ * @param name file name
+ * @param fileSystem file system
+ * @param builder <code>Http4FileSystemConfigBuilder</code> object
+ * @throws FileSystemException if any error occurs
+ * @throws URISyntaxException if given file name cannot be converted to a URI due to URI syntax error
+ */
+ protected Http4FileObject(final AbstractFileName name, final FS fileSystem,
+ final Http4FileSystemConfigBuilder builder) throws FileSystemException, URISyntaxException {
+ super(name, fileSystem);
+ final FileSystemOptions fileSystemOptions = fileSystem.getFileSystemOptions();
+ urlCharset = builder.getUrlCharset(fileSystemOptions);
+ final String pathEncoded = ((GenericURLFileName) name).getPathQueryEncoded(getUrlCharset());
+ internalURI = URIUtils.resolve(fileSystem.getInternalBaseURI(), pathEncoded);
+ }
+
+ @Override
+ protected FileType doGetType() throws Exception {
+ lastHeadResponse = executeHttpUriRequest(new HttpHead(getInternalURI()));
+ final int status = lastHeadResponse.getStatusLine().getStatusCode();
+
+ if (status == HttpStatus.SC_OK
+ || status == HttpStatus.SC_METHOD_NOT_ALLOWED /* method is not allowed, but resource exist */) {
+ return FileType.FILE;
+ } else if (status == HttpStatus.SC_NOT_FOUND || status == HttpStatus.SC_GONE) {
+ return FileType.IMAGINARY;
+ } else {
+ throw new FileSystemException("vfs.provider.http/head.error", getName(), Integer.valueOf(status));
+ }
+ }
+
+ @Override
+ protected long doGetContentSize() throws Exception {
+ if (lastHeadResponse == null) {
+ return 0L;
+ }
+
+ final Header header = lastHeadResponse.getFirstHeader(HTTP.CONTENT_LEN);
+
+ if (header == null) {
+ // Assume 0 content-length
+ return 0;
+ }
+
+ return Long.parseLong(header.getValue());
+ }
+
+ @Override
+ protected long doGetLastModifiedTime() throws Exception {
+ if (lastHeadResponse == null) {
+ throw new FileSystemException("vfs.provider.http/last-modified.error", getName());
+ }
+
+ final Header header = lastHeadResponse.getFirstHeader("Last-Modified");
+
+ if (header == null) {
+ throw new FileSystemException("vfs.provider.http/last-modified.error", getName());
+ }
+
+ return DateUtils.parseDate(header.getValue()).getTime();
+ }
+
+
+ @Override
+ protected InputStream doGetInputStream() throws Exception {
+ final HttpGet getRequest = new HttpGet(getInternalURI());
+ final HttpResponse httpResponse = executeHttpUriRequest(getRequest);
+ final int status = httpResponse.getStatusLine().getStatusCode();
+
+ if (status == HttpStatus.SC_NOT_FOUND) {
+ throw new FileNotFoundException(getName());
+ }
+
+ if (status != HttpStatus.SC_OK) {
+ throw new FileSystemException("vfs.provider.http/get.error", getName(), Integer.valueOf(status));
+ }
+
+ return new MonitoredHttpResponseContentInputStream(httpResponse);
+ }
+
+ @Override
+ protected RandomAccessContent doGetRandomAccessContent(final RandomAccessMode mode) throws Exception {
+ return new Http4RandomAccessContent<>(this, mode);
+ }
+
+ @Override
+ protected String[] doListChildren() throws Exception {
+ throw new UnsupportedOperationException("Not implemented.");
+ }
+
+ @Override
+ protected boolean doIsWriteable() throws Exception {
+ return false;
+ }
+
+ @Override
+ protected FileContentInfoFactory getFileContentInfoFactory() {
+ return new Http4FileContentInfoFactory();
+ }
+
+ @Override
+ protected void doDetach() throws Exception {
+ lastHeadResponse = null;
+ }
+
+ /**
+ * Return URL charset string.
+ * @return URL charset string
+ */
+ protected String getUrlCharset() {
+ return urlCharset;
+ }
+
+ /**
+ * Return the internal <code>URI</code> object mapped to this file object.
+ * @return the internal <code>URI</code> object mapped to this file object
+ * @throws FileSystemException if any error occurs
+ */
+ protected URI getInternalURI() throws FileSystemException {
+ return internalURI;
+ }
+
+ /**
+ * Return the last executed HEAD <code>HttpResponse</code> object.
+ * @return the last executed HEAD <code>HttpResponse</code> object
+ * @throws IOException if IO error occurs
+ */
+ HttpResponse getLastHeadResponse() throws IOException {
+ if (lastHeadResponse != null) {
+ return lastHeadResponse;
+ }
+
+ return executeHttpUriRequest(new HttpHead(getInternalURI()));
+ }
+
+ /**
+ * Execute the request using the given {@code httpRequest} and return a <code>HttpResponse</code> from the execution.
+ * @param httpRequest <code>HttpUriRequest</code> object
+ * @return <code>HttpResponse</code> from the execution
+ * @throws IOException if IO error occurs
+ */
+ HttpResponse executeHttpUriRequest(final HttpUriRequest httpRequest) throws IOException {
+ final HttpClient httpClient = getAbstractFileSystem().getHttpClient();
+ final HttpClientContext httpClientContext = getAbstractFileSystem().getHttpClientContext();
+ return httpClient.execute(httpRequest, httpClientContext);
+ }
+
+}
Added: commons/proper/vfs/trunk/commons-vfs2/src/main/java/org/apache/commons/vfs2/provider/http4/Http4FileProvider.java
URL: http://svn.apache.org/viewvc/commons/proper/vfs/trunk/commons-vfs2/src/main/java/org/apache/commons/vfs2/provider/http4/Http4FileProvider.java?rev=1845527&view=auto
==============================================================================
--- commons/proper/vfs/trunk/commons-vfs2/src/main/java/org/apache/commons/vfs2/provider/http4/Http4FileProvider.java (added)
+++ commons/proper/vfs/trunk/commons-vfs2/src/main/java/org/apache/commons/vfs2/provider/http4/Http4FileProvider.java Fri Nov 2 01:53:29 2018
@@ -0,0 +1,363 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.commons.vfs2.provider.http4;
+
+import java.io.File;
+import java.io.IOException;
+import java.net.ProxySelector;
+import java.security.KeyManagementException;
+import java.security.KeyStoreException;
+import java.security.NoSuchAlgorithmException;
+import java.security.cert.CertificateException;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.List;
+
+import javax.net.ssl.HostnameVerifier;
+import javax.net.ssl.SSLContext;
+
+import org.apache.commons.vfs2.Capability;
+import org.apache.commons.vfs2.FileName;
+import org.apache.commons.vfs2.FileSystem;
+import org.apache.commons.vfs2.FileSystemConfigBuilder;
+import org.apache.commons.vfs2.FileSystemException;
+import org.apache.commons.vfs2.FileSystemOptions;
+import org.apache.commons.vfs2.UserAuthenticationData;
+import org.apache.commons.vfs2.UserAuthenticator;
+import org.apache.commons.vfs2.provider.AbstractOriginatingFileProvider;
+import org.apache.commons.vfs2.provider.GenericFileName;
+import org.apache.commons.vfs2.util.UserAuthenticatorUtils;
+import org.apache.http.ConnectionReuseStrategy;
+import org.apache.http.Header;
+import org.apache.http.HttpHost;
+import org.apache.http.auth.AuthScope;
+import org.apache.http.auth.UsernamePasswordCredentials;
+import org.apache.http.client.AuthCache;
+import org.apache.http.client.CookieStore;
+import org.apache.http.client.CredentialsProvider;
+import org.apache.http.client.HttpClient;
+import org.apache.http.client.config.RequestConfig;
+import org.apache.http.client.protocol.HttpClientContext;
+import org.apache.http.config.SocketConfig;
+import org.apache.http.conn.HttpClientConnectionManager;
+import org.apache.http.conn.routing.HttpRoutePlanner;
+import org.apache.http.conn.ssl.DefaultHostnameVerifier;
+import org.apache.http.conn.ssl.NoopHostnameVerifier;
+import org.apache.http.conn.ssl.TrustAllStrategy;
+import org.apache.http.cookie.Cookie;
+import org.apache.http.impl.DefaultConnectionReuseStrategy;
+import org.apache.http.impl.NoConnectionReuseStrategy;
+import org.apache.http.impl.auth.BasicScheme;
+import org.apache.http.impl.client.BasicAuthCache;
+import org.apache.http.impl.client.BasicCookieStore;
+import org.apache.http.impl.client.BasicCredentialsProvider;
+import org.apache.http.impl.client.HttpClientBuilder;
+import org.apache.http.impl.client.HttpClients;
+import org.apache.http.impl.conn.DefaultProxyRoutePlanner;
+import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
+import org.apache.http.impl.conn.SystemDefaultRoutePlanner;
+import org.apache.http.message.BasicHeader;
+import org.apache.http.protocol.HTTP;
+import org.apache.http.ssl.SSLContextBuilder;
+
+/**
+ * <code>FileProvider</code> implementation using HttpComponents HttpClient library.
+ */
+public class Http4FileProvider extends AbstractOriginatingFileProvider {
+
+ /** Authenticator information. */
+ static final UserAuthenticationData.Type[] AUTHENTICATOR_TYPES =
+ new UserAuthenticationData.Type[] {
+ UserAuthenticationData.USERNAME,
+ UserAuthenticationData.PASSWORD
+ };
+
+ /** FileProvider capabilities */
+ static final Collection<Capability> capabilities =
+ Collections.unmodifiableCollection(
+ Arrays.asList(
+ Capability.GET_TYPE,
+ Capability.READ_CONTENT,
+ Capability.URI,
+ Capability.GET_LAST_MODIFIED,
+ Capability.ATTRIBUTES,
+ Capability.RANDOM_ACCESS_READ,
+ Capability.DIRECTORY_READ_CONTENT
+ )
+ );
+
+ /**
+ * Constructs a new provider.
+ */
+ public Http4FileProvider() {
+ super();
+ setFileNameParser(Http4FileNameParser.getInstance());
+ }
+
+ @Override
+ public FileSystemConfigBuilder getConfigBuilder() {
+ return Http4FileSystemConfigBuilder.getInstance();
+ }
+
+ @Override
+ public Collection<Capability> getCapabilities() {
+ return capabilities;
+ }
+
+ @Override
+ protected FileSystem doCreateFileSystem(FileName name, FileSystemOptions fileSystemOptions)
+ throws FileSystemException {
+ final GenericFileName rootName = (GenericFileName) name;
+
+ UserAuthenticationData authData = null;
+ HttpClient httpClient = null;
+ HttpClientContext httpClientContext = null;
+
+ try {
+ final Http4FileSystemConfigBuilder builder = Http4FileSystemConfigBuilder.getInstance();
+ authData = UserAuthenticatorUtils.authenticate(fileSystemOptions, AUTHENTICATOR_TYPES);
+ httpClientContext = createHttpClientContext(builder, rootName, fileSystemOptions, authData);
+ httpClient = createHttpClient(builder, rootName, fileSystemOptions);
+ } finally {
+ UserAuthenticatorUtils.cleanup(authData);
+ }
+
+ return new Http4FileSystem(rootName, fileSystemOptions, httpClient, httpClientContext);
+ }
+
+ /**
+ * Create an {@link HttpClient} object for an http4 file system.
+ * @param builder Configuration options builder for http4 provider
+ * @param rootName The root path
+ * @param fileSystemOptions The file system options
+ * @return an {@link HttpClient} object
+ * @throws FileSystemException if an error occurs.
+ */
+ protected HttpClient createHttpClient(final Http4FileSystemConfigBuilder builder, final GenericFileName rootName,
+ final FileSystemOptions fileSystemOptions) throws FileSystemException {
+ return createHttpClientBuilder(builder, rootName, fileSystemOptions).build();
+ }
+
+ /**
+ * Create an {@link HttpClientBuilder} object. Invoked by {@link #createHttpClient(Http4FileSystemConfigBuilder, GenericFileName, FileSystemOptions)}.
+ * @param builder Configuration options builder for HTTP4 provider
+ * @param rootName The root path
+ * @param fileSystemOptions The FileSystem options
+ * @return an {@link HttpClientBuilder} object
+ * @throws FileSystemException if an error occurs
+ */
+ protected HttpClientBuilder createHttpClientBuilder(final Http4FileSystemConfigBuilder builder, final GenericFileName rootName,
+ final FileSystemOptions fileSystemOptions) throws FileSystemException {
+ final List<Header> defaultHeaders = new ArrayList<>();
+ defaultHeaders.add(new BasicHeader(HTTP.USER_AGENT, builder.getUserAgent(fileSystemOptions)));
+
+ final ConnectionReuseStrategy connectionReuseStrategy = builder.isKeepAlive(fileSystemOptions)
+ ? DefaultConnectionReuseStrategy.INSTANCE
+ : NoConnectionReuseStrategy.INSTANCE;
+
+ final HttpClientBuilder httpClientBuilder =
+ HttpClients.custom()
+ .setRoutePlanner(createHttpRoutePlanner(builder, fileSystemOptions))
+ .setConnectionManager(createConnectionManager(builder, fileSystemOptions))
+ .setSSLContext(createSSLContext(builder, fileSystemOptions))
+ .setSSLHostnameVerifier(createHostnameVerifier(builder, fileSystemOptions))
+ .setConnectionReuseStrategy(connectionReuseStrategy)
+ .setDefaultRequestConfig(createDefaultRequestConfig(builder, fileSystemOptions))
+ .setDefaultHeaders(defaultHeaders)
+ .setDefaultCookieStore(createDefaultCookieStore(builder, fileSystemOptions));
+
+ if (!builder.getFollowRedirect(fileSystemOptions)) {
+ httpClientBuilder.disableRedirectHandling();
+ }
+
+ return httpClientBuilder;
+ }
+
+ /**
+ * Create {@link SSLContext} for HttpClient. Invoked by {@link #createHttpClientBuilder(Http4FileSystemConfigBuilder, GenericFileName, FileSystemOptions)}.
+ * @param builder Configuration options builder for HTTP4 provider
+ * @param fileSystemOptions The FileSystem options
+ * @return a {@link SSLContext} for HttpClient
+ * @throws FileSystemException if an error occurs
+ */
+ protected SSLContext createSSLContext(final Http4FileSystemConfigBuilder builder,
+ final FileSystemOptions fileSystemOptions) throws FileSystemException {
+ try {
+ final SSLContextBuilder sslContextBuilder = new SSLContextBuilder();
+
+ File keystoreFileObject = null;
+ final String keystoreFile = builder.getKeyStoreFile(fileSystemOptions);
+
+ if (keystoreFile != null && !keystoreFile.isEmpty()) {
+ keystoreFileObject = new File(keystoreFile);
+ }
+
+ if (keystoreFileObject != null && keystoreFileObject.exists()) {
+ final String keystorePass = builder.getKeyStorePass(fileSystemOptions);
+ final char[] keystorePassChars = (keystorePass != null) ? keystorePass.toCharArray() : null;
+ sslContextBuilder.loadTrustMaterial(keystoreFileObject, keystorePassChars, TrustAllStrategy.INSTANCE);
+ } else {
+ sslContextBuilder.loadTrustMaterial(TrustAllStrategy.INSTANCE);
+ }
+
+ return sslContextBuilder.build();
+ } catch (KeyStoreException e) {
+ throw new FileSystemException("Keystore error. " + e.getMessage(), e);
+ } catch (KeyManagementException e) {
+ throw new FileSystemException("Cannot retrieve keys. " + e.getMessage(), e);
+ } catch (NoSuchAlgorithmException e) {
+ throw new FileSystemException("Algorithm error. " + e.getMessage(), e);
+ } catch (CertificateException e) {
+ throw new FileSystemException("Certificate error. " + e.getMessage(), e);
+ } catch (IOException e) {
+ throw new FileSystemException("Cannot open key file. " + e.getMessage(), e);
+ }
+ }
+
+ /**
+ * Create an {@link HttpClientContext} object for an http4 file system.
+ * @param builder Configuration options builder for http4 provider
+ * @param rootName The root path
+ * @param fileSystemOptions The FileSystem options
+ * @param authData The <code>UserAuthentiationData</code> object
+ * @return an {@link HttpClientContext} object
+ * @throws FileSystemException if an error occurs
+ */
+ protected HttpClientContext createHttpClientContext(final Http4FileSystemConfigBuilder builder,
+ final GenericFileName rootName, final FileSystemOptions fileSystemOptions,
+ final UserAuthenticationData authData) throws FileSystemException {
+
+ final HttpClientContext clientContext = HttpClientContext.create();
+ final CredentialsProvider credsProvider = new BasicCredentialsProvider();
+ clientContext.setCredentialsProvider(credsProvider);
+
+ final String username = UserAuthenticatorUtils.toString(UserAuthenticatorUtils.getData(authData,
+ UserAuthenticationData.USERNAME, UserAuthenticatorUtils.toChar(rootName.getUserName())));
+ final String password = UserAuthenticatorUtils.toString(UserAuthenticatorUtils.getData(authData,
+ UserAuthenticationData.PASSWORD, UserAuthenticatorUtils.toChar(rootName.getPassword())));
+
+ if (username != null && !username.isEmpty()) {
+ credsProvider.setCredentials(new AuthScope(rootName.getHostName(), AuthScope.ANY_PORT),
+ new UsernamePasswordCredentials(username, password));
+ }
+
+ final HttpHost proxyHost = getProxyHttpHost(builder, fileSystemOptions);
+
+ if (proxyHost != null) {
+ final UserAuthenticator proxyAuth = builder.getProxyAuthenticator(fileSystemOptions);
+
+ if (proxyAuth != null) {
+ final UserAuthenticationData proxyAuthData = UserAuthenticatorUtils.authenticate(proxyAuth,
+ new UserAuthenticationData.Type[] { UserAuthenticationData.USERNAME,
+ UserAuthenticationData.PASSWORD });
+
+ if (proxyAuthData != null) {
+ final UsernamePasswordCredentials proxyCreds = new UsernamePasswordCredentials(
+ UserAuthenticatorUtils.toString(
+ UserAuthenticatorUtils.getData(authData, UserAuthenticationData.USERNAME, null)),
+ UserAuthenticatorUtils.toString(
+ UserAuthenticatorUtils.getData(authData, UserAuthenticationData.PASSWORD, null)));
+
+ credsProvider.setCredentials(new AuthScope(proxyHost.getHostName(), AuthScope.ANY_PORT),
+ proxyCreds);
+ }
+
+ if (builder.isPreemptiveAuth(fileSystemOptions)) {
+ final AuthCache authCache = new BasicAuthCache();
+ final BasicScheme basicAuth = new BasicScheme();
+ authCache.put(proxyHost, basicAuth);
+ clientContext.setAuthCache(authCache);
+ }
+ }
+ }
+
+ return clientContext;
+ }
+
+ private HttpClientConnectionManager createConnectionManager(final Http4FileSystemConfigBuilder builder,
+ final FileSystemOptions fileSystemOptions) throws FileSystemException {
+ final PoolingHttpClientConnectionManager connManager = new PoolingHttpClientConnectionManager();
+ connManager.setMaxTotal(builder.getMaxTotalConnections(fileSystemOptions));
+ connManager.setDefaultMaxPerRoute(builder.getMaxConnectionsPerHost(fileSystemOptions));
+
+ final SocketConfig socketConfig =
+ SocketConfig
+ .custom()
+ .setSoTimeout(builder.getSoTimeout(fileSystemOptions))
+ .build();
+
+ connManager.setDefaultSocketConfig(socketConfig);
+
+ return connManager;
+ }
+
+ private RequestConfig createDefaultRequestConfig(final Http4FileSystemConfigBuilder builder,
+ final FileSystemOptions fileSystemOptions) {
+ return RequestConfig.custom()
+ .setConnectTimeout(builder.getConnectionTimeout(fileSystemOptions))
+ .build();
+ }
+
+ private HttpRoutePlanner createHttpRoutePlanner(final Http4FileSystemConfigBuilder builder,
+ final FileSystemOptions fileSystemOptions) {
+ final HttpHost proxyHost = getProxyHttpHost(builder, fileSystemOptions);
+
+ if (proxyHost != null) {
+ return new DefaultProxyRoutePlanner(proxyHost);
+ }
+
+ return new SystemDefaultRoutePlanner(ProxySelector.getDefault());
+ }
+
+ private HttpHost getProxyHttpHost(final Http4FileSystemConfigBuilder builder,
+ final FileSystemOptions fileSystemOptions) {
+ final String proxyHost = builder.getProxyHost(fileSystemOptions);
+ final int proxyPort = builder.getProxyPort(fileSystemOptions);
+
+ if (proxyHost != null && proxyHost.length() > 0 && proxyPort > 0) {
+ return new HttpHost(proxyHost, proxyPort);
+ }
+
+ return null;
+ }
+
+ private CookieStore createDefaultCookieStore(final Http4FileSystemConfigBuilder builder,
+ final FileSystemOptions fileSystemOptions) {
+ final CookieStore cookieStore = new BasicCookieStore();
+ final Cookie[] cookies = builder.getCookies(fileSystemOptions);
+
+ if (cookies != null) {
+ for (Cookie cookie : cookies) {
+ cookieStore.addCookie(cookie);
+ }
+ }
+
+ return cookieStore;
+ }
+
+ private HostnameVerifier createHostnameVerifier(final Http4FileSystemConfigBuilder builder,
+ final FileSystemOptions fileSystemOptions) throws FileSystemException {
+ if (!builder.isHostnameVerificationEnabled(fileSystemOptions)) {
+ return NoopHostnameVerifier.INSTANCE;
+ }
+
+ return new DefaultHostnameVerifier();
+ }
+
+}
Added: commons/proper/vfs/trunk/commons-vfs2/src/main/java/org/apache/commons/vfs2/provider/http4/Http4FileSystem.java
URL: http://svn.apache.org/viewvc/commons/proper/vfs/trunk/commons-vfs2/src/main/java/org/apache/commons/vfs2/provider/http4/Http4FileSystem.java?rev=1845527&view=auto
==============================================================================
--- commons/proper/vfs/trunk/commons-vfs2/src/main/java/org/apache/commons/vfs2/provider/http4/Http4FileSystem.java (added)
+++ commons/proper/vfs/trunk/commons-vfs2/src/main/java/org/apache/commons/vfs2/provider/http4/Http4FileSystem.java Fri Nov 2 01:53:29 2018
@@ -0,0 +1,123 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.commons.vfs2.provider.http4;
+
+import java.io.IOException;
+import java.net.URI;
+import java.util.Collection;
+
+import org.apache.commons.vfs2.Capability;
+import org.apache.commons.vfs2.FileName;
+import org.apache.commons.vfs2.FileObject;
+import org.apache.commons.vfs2.FileSystemOptions;
+import org.apache.commons.vfs2.provider.AbstractFileName;
+import org.apache.commons.vfs2.provider.AbstractFileSystem;
+import org.apache.http.client.HttpClient;
+import org.apache.http.client.protocol.HttpClientContext;
+import org.apache.http.impl.client.CloseableHttpClient;
+
+/**
+ * http4 file system.
+ */
+public class Http4FileSystem extends AbstractFileSystem {
+
+ /**
+ * Internal base URI of this file system.
+ */
+ private final URI internalBaseURI;
+
+ /**
+ * Internal <code>HttpClient</code> instance of this file system.
+ */
+ private final HttpClient httpClient;
+
+ /**
+ * Internal <code>HttpClientContext</code> instance of this file system.
+ */
+ private final HttpClientContext httpClientContext;
+
+ /**
+ * Construct <code>Http4FileSystem</code>.
+ * @param rootName root base name
+ * @param fileSystemOptions file system options
+ * @param httpClient {@link HttpClient} instance
+ * @param httpClientContext {@link HttpClientContext} instance
+ */
+ protected Http4FileSystem(FileName rootName, FileSystemOptions fileSystemOptions, HttpClient httpClient,
+ HttpClientContext httpClientContext) {
+ super(rootName, null, fileSystemOptions);
+
+ final String rootURI = getRootURI();
+ final int offset = rootURI.indexOf(':');
+ final char lastCharOfScheme = (offset > 0) ? rootURI.charAt(offset - 1) : 0;
+
+ // if scheme is 'http*s' or 'HTTP*S', then the internal base URI should be 'https'. 'http' otherwise.
+ if (lastCharOfScheme == 's' || lastCharOfScheme == 'S') {
+ this.internalBaseURI = URI.create("https" + rootURI.substring(offset));
+ } else {
+ this.internalBaseURI = URI.create("http" + rootURI.substring(offset));
+ }
+
+ this.httpClient = httpClient;
+ this.httpClientContext = httpClientContext;
+ }
+
+ @Override
+ protected FileObject createFile(AbstractFileName name) throws Exception {
+ return new Http4FileObject<>(name, this);
+ }
+
+ @Override
+ protected void addCapabilities(Collection<Capability> caps) {
+ caps.addAll(Http4FileProvider.capabilities);
+ }
+
+ @Override
+ protected void doCloseCommunicationLink() {
+ if (httpClient instanceof CloseableHttpClient) {
+ try {
+ ((CloseableHttpClient) httpClient).close();
+ } catch (IOException e) {
+ throw new RuntimeException("Error closing HttpClient", e);
+ }
+ }
+ }
+
+ /**
+ * Return the internal {@link HttpClient} instance.
+ * @return the internal {@link HttpClient} instance
+ */
+ protected HttpClient getHttpClient() {
+ return httpClient;
+ }
+
+ /**
+ * Return the internal {@link HttpClientContext} instance.
+ * @return the internal {@link HttpClientContext} instance
+ */
+ protected HttpClientContext getHttpClientContext() {
+ return httpClientContext;
+ }
+
+ /**
+ * Return the internal base <code>URI</code> instance.
+ * @return the internal base <code>URI</code> instance
+ */
+ protected URI getInternalBaseURI() {
+ return internalBaseURI;
+ }
+}
Added: commons/proper/vfs/trunk/commons-vfs2/src/main/java/org/apache/commons/vfs2/provider/http4/Http4FileSystemConfigBuilder.java
URL: http://svn.apache.org/viewvc/commons/proper/vfs/trunk/commons-vfs2/src/main/java/org/apache/commons/vfs2/provider/http4/Http4FileSystemConfigBuilder.java?rev=1845527&view=auto
==============================================================================
--- commons/proper/vfs/trunk/commons-vfs2/src/main/java/org/apache/commons/vfs2/provider/http4/Http4FileSystemConfigBuilder.java (added)
+++ commons/proper/vfs/trunk/commons-vfs2/src/main/java/org/apache/commons/vfs2/provider/http4/Http4FileSystemConfigBuilder.java Fri Nov 2 01:53:29 2018
@@ -0,0 +1,515 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.commons.vfs2.provider.http4;
+
+import org.apache.commons.vfs2.FileSystem;
+import org.apache.commons.vfs2.FileSystemConfigBuilder;
+import org.apache.commons.vfs2.FileSystemOptions;
+import org.apache.commons.vfs2.UserAuthenticator;
+import org.apache.http.cookie.Cookie;
+
+/**
+ * Configuration options builder utility for http4 provider.
+ */
+public class Http4FileSystemConfigBuilder extends FileSystemConfigBuilder {
+
+ private static final Http4FileSystemConfigBuilder BUILDER = new Http4FileSystemConfigBuilder();
+
+ /**
+ * Defines the maximum number of connections allowed overall. This value only applies
+ * to the number of connections from a particular instance of HTTP connection manager.
+ * <p>
+ * This parameter expects a value of type {@link Integer}.
+ * </p>
+ */
+ private static final String MAX_TOTAL_CONNECTIONS = "http.connection-manager.max-total";
+
+ /**
+ * Defines the maximum number of connections allowed per host configuration.
+ * These values only apply to the number of connections from a particular instance
+ * of HTTP connection manager.
+ */
+ private static final String MAX_HOST_CONNECTIONS = "http.connection-manager.max-per-host";
+
+ /**
+ * Defines the connection timeout of an HTTP request.
+ * <p>
+ * This parameter expects a value of type {@link Integer}.
+ * </p>
+ */
+ private static final String CONNECTION_TIMEOUT = "http.connection.timeout";
+
+ /**
+ * Defines the socket timeout of an HTTP request.
+ * <p>
+ * This parameter expects a value of type {@link Integer}.
+ * </p>
+ */
+ private static final String SO_TIMEOUT = "http.socket.timeout";
+
+ /**
+ * Defines whether Keep-Alive option is used or not.
+ * <p>
+ * This parameter expects a value of type {@link Boolean}.
+ * </p>
+ */
+ private static final String KEEP_ALIVE = "http.keepAlive";
+
+ /**
+ * Defines the keystore file path for SSL connections.
+ * <p>
+ * This parameter expects a value of type {@link String}.
+ * </p>
+ */
+ private static final String KEYSTORE_FILE = "http.keystoreFile";
+
+ /**
+ * Defines the keystore pass phrase for SSL connections.
+ * <p>
+ * This parameter expects a value of type {@link String}.
+ * </p>
+ */
+ private static final String KEYSTORE_PASS = "http.keystorePass";
+
+ /**
+ * Defines whether the host name should be verified or not in SSL connections.
+ * <p>
+ * This parameter expects a value of type {@link Boolean}.
+ * </p>
+ */
+ private static final String HOSTNAME_VERIFICATION_ENABLED = "http.hostname-verification.enabled";
+
+ /**
+ * Defines whether the HttpClient should follow redirections from the responses.
+ * <p>
+ * This parameter expects a value of type {@link Boolean}.
+ * </p>
+ */
+ private static final String KEY_FOLLOW_REDIRECT = "followRedirect";
+
+ /**
+ * Defines the User-Agent request header string of the underlying HttpClient.
+ * <p>
+ * This parameter expects a value of type {@link String}.
+ * </p>
+ */
+ private static final String KEY_USER_AGENT = "userAgent";
+
+ /**
+ * Defines whether the preemptive authentication should be enabled or not.
+ * <p>
+ * This parameter expects a value of type {@link Boolean}.
+ * </p>
+ */
+ private static final String KEY_PREEMPTIVE_AUTHENTICATION = "preemptiveAuth";
+
+ /**
+ * The default value for {@link #MAX_TOTAL_CONNECTIONS} configuration.
+ */
+ private static final int DEFAULT_MAX_CONNECTIONS = 50;
+
+ /**
+ * The default value for {@link #MAX_HOST_CONNECTIONS} configuration.
+ */
+ private static final int DEFAULT_MAX_HOST_CONNECTIONS = 5;
+
+ /**
+ * The default value for {@link #CONNECTION_TIMEOUT} configuration.
+ */
+ private static final int DEFAULT_CONNECTION_TIMEOUT = 0;
+
+ /**
+ * The default value for {@link #SO_TIMEOUT} configuration.
+ */
+ private static final int DEFAULT_SO_TIMEOUT = 0;
+
+ /**
+ * The default value for {@link #KEEP_ALIVE} configuration.
+ */
+ private static final boolean DEFAULT_KEEP_ALIVE = true;
+
+ /**
+ * The default value for {@link #KEY_FOLLOW_REDIRECT} configuration.
+ */
+ private static final boolean DEFAULT_FOLLOW_REDIRECT = true;
+
+ /**
+ * The default value for {@link #KEY_USER_AGENT} configuration.
+ */
+ private static final String DEFAULT_USER_AGENT = "Jakarta-Commons-VFS";
+
+ /**
+ * The default value for {@link #HOSTNAME_VERIFICATION_ENABLED} configuration.
+ */
+ private static final boolean DEFAULT_HOSTNAME_VERIFICATION_ENABLED = true;
+
+ /**
+ * Construct an <code>Http4FileSystemConfigBuilder</code>.
+ *
+ * @param prefix String for properties of this file system.
+ */
+ protected Http4FileSystemConfigBuilder(final String prefix) {
+ super(prefix);
+ }
+
+ private Http4FileSystemConfigBuilder() {
+ super("http.");
+ }
+
+ /**
+ * Gets the singleton builder.
+ *
+ * @return the singleton builder.
+ */
+ public static Http4FileSystemConfigBuilder getInstance() {
+ return BUILDER;
+ }
+
+ /**
+ * Sets the charset used for url encoding.<br>
+ *
+ * @param opts The FileSystem options.
+ * @param chaset the chaset
+ */
+ public void setUrlCharset(final FileSystemOptions opts, final String chaset) {
+ setParam(opts, "urlCharset", chaset);
+ }
+
+ /**
+ * Sets the charset used for url encoding.<br>
+ *
+ * @param opts The FileSystem options.
+ * @return the chaset
+ */
+ public String getUrlCharset(final FileSystemOptions opts) {
+ return getString(opts, "urlCharset");
+ }
+
+ /**
+ * Sets the proxy to use for http connection.<br>
+ * You have to set the ProxyPort too if you would like to have the proxy really used.
+ *
+ * @param opts The FileSystem options.
+ * @param proxyHost the host
+ * @see #setProxyPort
+ */
+ public void setProxyHost(final FileSystemOptions opts, final String proxyHost) {
+ setParam(opts, "proxyHost", proxyHost);
+ }
+
+ /**
+ * Sets the proxy-port to use for http connection. You have to set the ProxyHost too if you would like to have the
+ * proxy really used.
+ *
+ * @param opts The FileSystem options.
+ * @param proxyPort the port
+ * @see #setProxyHost
+ */
+ public void setProxyPort(final FileSystemOptions opts, final int proxyPort) {
+ setParam(opts, "proxyPort", Integer.valueOf(proxyPort));
+ }
+
+ /**
+ * Gets the proxy to use for http connection. You have to set the ProxyPort too if you would like to have the proxy
+ * really used.
+ *
+ * @param opts The FileSystem options.
+ * @return proxyHost
+ * @see #setProxyPort
+ */
+ public String getProxyHost(final FileSystemOptions opts) {
+ return getString(opts, "proxyHost");
+ }
+
+ /**
+ * Gets the proxy-port to use for http the connection. You have to set the ProxyHost too if you would like to have
+ * the proxy really used.
+ *
+ * @param opts The FileSystem options.
+ * @return proxyPort: the port number or 0 if it is not set
+ * @see #setProxyHost
+ */
+ public int getProxyPort(final FileSystemOptions opts) {
+ return getInteger(opts, "proxyPort", 0);
+ }
+
+ /**
+ * Sets the proxy authenticator where the system should get the credentials from.
+ *
+ * @param opts The FileSystem options.
+ * @param authenticator The UserAuthenticator.
+ */
+ public void setProxyAuthenticator(final FileSystemOptions opts, final UserAuthenticator authenticator) {
+ setParam(opts, "proxyAuthenticator", authenticator);
+ }
+
+ /**
+ * Gets the proxy authenticator where the system should get the credentials from.
+ *
+ * @param opts The FileSystem options.
+ * @return The UserAuthenticator.
+ */
+ public UserAuthenticator getProxyAuthenticator(final FileSystemOptions opts) {
+ return (UserAuthenticator) getParam(opts, "proxyAuthenticator");
+ }
+
+ /**
+ * The cookies to add to the request.
+ *
+ * @param opts The FileSystem options.
+ * @param cookies An array of Cookies.
+ */
+ public void setCookies(final FileSystemOptions opts, final Cookie[] cookies) {
+ setParam(opts, "cookies", cookies);
+ }
+
+ /**
+ * Sets whether to follow redirects for the connection.
+ *
+ * @param opts The FileSystem options.
+ * @param redirect {@code true} to follow redirects, {@code false} not to.
+ * @see #setFollowRedirect
+ */
+ public void setFollowRedirect(final FileSystemOptions opts, final boolean redirect) {
+ setParam(opts, KEY_FOLLOW_REDIRECT, redirect);
+ }
+
+ /**
+ * Gets the cookies to add to the request.
+ *
+ * @param opts The FileSystem options.
+ * @return the Cookie array.
+ */
+ public Cookie[] getCookies(final FileSystemOptions opts) {
+ return (Cookie[]) getParam(opts, "cookies");
+ }
+
+ /**
+ * Gets whether to follow redirects for the connection.
+ *
+ * @param opts The FileSystem options.
+ * @return {@code true} to follow redirects, {@code false} not to.
+ * @see #setFollowRedirect
+ */
+ public boolean getFollowRedirect(final FileSystemOptions opts) {
+ return getBoolean(opts, KEY_FOLLOW_REDIRECT, DEFAULT_FOLLOW_REDIRECT);
+ }
+
+ /**
+ * Sets the maximum number of connections allowed.
+ *
+ * @param opts The FileSystem options.
+ * @param maxTotalConnections The maximum number of connections.
+ */
+ public void setMaxTotalConnections(final FileSystemOptions opts, final int maxTotalConnections) {
+ setParam(opts, MAX_TOTAL_CONNECTIONS, Integer.valueOf(maxTotalConnections));
+ }
+
+ /**
+ * Gets the maximum number of connections allowed.
+ *
+ * @param opts The FileSystemOptions.
+ * @return The maximum number of connections allowed.
+ */
+ public int getMaxTotalConnections(final FileSystemOptions opts) {
+ return getInteger(opts, MAX_TOTAL_CONNECTIONS, DEFAULT_MAX_CONNECTIONS);
+ }
+
+ /**
+ * Sets the maximum number of connections allowed to any host.
+ *
+ * @param opts The FileSystem options.
+ * @param maxHostConnections The maximum number of connections to a host.
+ */
+ public void setMaxConnectionsPerHost(final FileSystemOptions opts, final int maxHostConnections) {
+ setParam(opts, MAX_HOST_CONNECTIONS, Integer.valueOf(maxHostConnections));
+ }
+
+ /**
+ * Gets the maximum number of connections allowed per host.
+ *
+ * @param opts The FileSystemOptions.
+ * @return The maximum number of connections allowed per host.
+ */
+ public int getMaxConnectionsPerHost(final FileSystemOptions opts) {
+ return getInteger(opts, MAX_HOST_CONNECTIONS, DEFAULT_MAX_HOST_CONNECTIONS);
+ }
+
+ /**
+ * Determines if the FileSystemOptions indicate that preemptive authentication is requested.
+ *
+ * @param opts The FileSystemOptions.
+ * @return true if preemptiveAuth is requested.
+ */
+ public boolean isPreemptiveAuth(final FileSystemOptions opts) {
+ return getBoolean(opts, KEY_PREEMPTIVE_AUTHENTICATION, Boolean.FALSE).booleanValue();
+ }
+
+ /**
+ * Sets the given value for preemptive HTTP authentication (using BASIC) on the given FileSystemOptions object.
+ * Defaults to false if not set. It may be appropriate to set to true in cases when the resulting chattiness of the
+ * conversation outweighs any architectural desire to use a stronger authentication scheme than basic/preemptive.
+ *
+ * @param opts The FileSystemOptions.
+ * @param preemptiveAuth the desired setting; true=enabled and false=disabled.
+ */
+ public void setPreemptiveAuth(final FileSystemOptions opts, final boolean preemptiveAuth) {
+ setParam(opts, KEY_PREEMPTIVE_AUTHENTICATION, Boolean.valueOf(preemptiveAuth));
+ }
+
+ /**
+ * The connection timeout.
+ *
+ * @param opts The FileSystem options.
+ * @param connectionTimeout The connection timeout.
+ */
+ public void setConnectionTimeout(final FileSystemOptions opts, final int connectionTimeout) {
+ setParam(opts, CONNECTION_TIMEOUT, Integer.valueOf(connectionTimeout));
+ }
+
+ /**
+ * Gets the connection timeout.
+ *
+ * @param opts The FileSystem options.
+ * @return The connection timeout.
+ */
+ public int getConnectionTimeout(final FileSystemOptions opts) {
+ return getInteger(opts, CONNECTION_TIMEOUT, DEFAULT_CONNECTION_TIMEOUT);
+ }
+
+ /**
+ * The socket timeout.
+ *
+ * @param opts The FileSystem options.
+ * @param soTimeout socket timeout.
+ */
+ public void setSoTimeout(final FileSystemOptions opts, final int soTimeout) {
+ setParam(opts, SO_TIMEOUT, Integer.valueOf(soTimeout));
+ }
+
+ /**
+ * Gets the socket timeout.
+ *
+ * @param opts The FileSystemOptions.
+ * @return The socket timeout.
+ */
+ public int getSoTimeout(final FileSystemOptions opts) {
+ return getInteger(opts, SO_TIMEOUT, DEFAULT_SO_TIMEOUT);
+ }
+
+ /**
+ * Sets if the FileSystemOptions indicate that HTTP Keep-Alive is respected.
+ *
+ * @param opts The FileSystemOptions.
+ * @param keepAlive whether the FileSystemOptions indicate that HTTP Keep-Alive is respected or not.
+ */
+ public void setKeepAlive(final FileSystemOptions opts, boolean keepAlive) {
+ setParam(opts, KEEP_ALIVE, Boolean.valueOf(keepAlive));
+ }
+
+ /**
+ * Determines if the FileSystemOptions indicate that HTTP Keep-Alive is respected.
+ *
+ * @param opts The FileSystemOptions.
+ * @return true if if the FileSystemOptions indicate that HTTP Keep-Alive is respected.
+ */
+ public boolean isKeepAlive(final FileSystemOptions opts) {
+ return getBoolean(opts, KEEP_ALIVE, DEFAULT_KEEP_ALIVE);
+ }
+
+ /**
+ * Sets the user agent to attach to the outgoing http methods
+ *
+ * @param opts the file system options to modify
+ * @param userAgent User Agent String
+ */
+ public void setUserAgent(final FileSystemOptions opts, final String userAgent) {
+ setParam(opts, "userAgent", userAgent);
+ }
+
+ /**
+ * Gets the user agent string
+ *
+ * @param opts the file system options to modify
+ * @return User provided User-Agent string, otherwise default of: Commons-VFS
+ */
+ public String getUserAgent(final FileSystemOptions opts) {
+ final String userAgent = (String) getParam(opts, KEY_USER_AGENT);
+ return userAgent != null ? userAgent : DEFAULT_USER_AGENT;
+ }
+
+ /**
+ * Set keystore file path for SSL connections.
+ * @param opts the file system options to modify
+ * @param keyStoreFile keystore file path
+ */
+ public void setKeyStoreFile(final FileSystemOptions opts, String keyStoreFile) {
+ setParam(opts, KEYSTORE_FILE, keyStoreFile);
+ }
+
+ /**
+ * Return keystore file path to be used in SSL connections.
+ * @param opts the file system options to modify
+ * @return keystore file path to be used in SSL connections
+ */
+ public String getKeyStoreFile(final FileSystemOptions opts) {
+ return (String) getParam(opts, KEYSTORE_FILE);
+ }
+
+ /**
+ * Set keystore pass phrase for SSL connecdtions.
+ * @param opts the file system options to modify
+ * @param keyStorePass keystore pass phrase for SSL connecdtions
+ */
+ public void setKeyStorePass(final FileSystemOptions opts, String keyStorePass) {
+ setParam(opts, KEYSTORE_PASS, keyStorePass);
+ }
+
+ /**
+ * Return keystore pass phrase for SSL connections.
+ * @param opts the file system options to modify
+ * @return keystore pass phrase for SSL connections
+ */
+ String getKeyStorePass(final FileSystemOptions opts) {
+ return (String) getParam(opts, KEYSTORE_PASS);
+ }
+
+ /**
+ * Sets if the hostname should be verified in SSL context.
+ *
+ * @param opts The FileSystemOptions.
+ * @param hostnameVerificationEnabled whether hostname should be verified
+ */
+ public void setHostnameVerificationEnabled(final FileSystemOptions opts, boolean hostnameVerificationEnabled) {
+ setParam(opts, HOSTNAME_VERIFICATION_ENABLED, Boolean.valueOf(hostnameVerificationEnabled));
+ }
+
+ /**
+ * Determines if the hostname should be verified in SSL context.
+ *
+ * @param opts The FileSystemOptions.
+ * @return true if if the FileSystemOptions indicate that HTTP Keep-Alive is respected.
+ */
+ public boolean isHostnameVerificationEnabled(final FileSystemOptions opts) {
+ return getBoolean(opts, HOSTNAME_VERIFICATION_ENABLED, DEFAULT_HOSTNAME_VERIFICATION_ENABLED);
+ }
+
+ @Override
+ protected Class<? extends FileSystem> getConfigClass() {
+ return Http4FileSystem.class;
+ }
+}
Added: commons/proper/vfs/trunk/commons-vfs2/src/main/java/org/apache/commons/vfs2/provider/http4/Http4RandomAccessContent.java
URL: http://svn.apache.org/viewvc/commons/proper/vfs/trunk/commons-vfs2/src/main/java/org/apache/commons/vfs2/provider/http4/Http4RandomAccessContent.java?rev=1845527&view=auto
==============================================================================
--- commons/proper/vfs/trunk/commons-vfs2/src/main/java/org/apache/commons/vfs2/provider/http4/Http4RandomAccessContent.java (added)
+++ commons/proper/vfs/trunk/commons-vfs2/src/main/java/org/apache/commons/vfs2/provider/http4/Http4RandomAccessContent.java Fri Nov 2 01:53:29 2018
@@ -0,0 +1,143 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.commons.vfs2.provider.http4;
+
+import java.io.DataInputStream;
+import java.io.FilterInputStream;
+import java.io.IOException;
+import java.net.HttpURLConnection;
+
+import org.apache.commons.vfs2.FileSystemException;
+import org.apache.commons.vfs2.provider.AbstractRandomAccessStreamContent;
+import org.apache.commons.vfs2.util.MonitorInputStream;
+import org.apache.commons.vfs2.util.RandomAccessMode;
+import org.apache.http.HttpResponse;
+import org.apache.http.client.methods.HttpGet;
+
+/**
+ * RandomAccess content using <code>Http4FileObject</code>.
+ */
+class Http4RandomAccessContent<FS extends Http4FileSystem> extends AbstractRandomAccessStreamContent {
+
+ protected long filePointer = 0;
+
+ private final Http4FileObject<FS> fileObject;
+
+ private DataInputStream dis = null;
+ private MonitorInputStream mis = null;
+
+ Http4RandomAccessContent(final Http4FileObject<FS> fileObject, final RandomAccessMode mode) {
+ super(mode);
+ this.fileObject = fileObject;
+ }
+
+ @Override
+ public long getFilePointer() throws IOException {
+ return filePointer;
+ }
+
+ @Override
+ public void seek(final long pos) throws IOException {
+ if (pos == filePointer) {
+ // no change
+ return;
+ }
+
+ if (pos < 0) {
+ throw new FileSystemException("vfs.provider/random-access-invalid-position.error", Long.valueOf(pos));
+ }
+
+ if (dis != null) {
+ close();
+ }
+
+ filePointer = pos;
+ }
+
+ @Override
+ protected DataInputStream getDataInputStream() throws IOException {
+ if (dis != null) {
+ return dis;
+ }
+
+ final HttpGet httpGet = new HttpGet(fileObject.getInternalURI());
+ httpGet.setHeader("Range", "bytes=" + filePointer + "-");
+ final HttpResponse httpResponse = fileObject.executeHttpUriRequest(httpGet);
+ final int status = httpResponse.getStatusLine().getStatusCode();
+
+ if (status != HttpURLConnection.HTTP_PARTIAL && status != HttpURLConnection.HTTP_OK) {
+ throw new FileSystemException("vfs.provider.http/get-range.error", fileObject.getName(),
+ Long.valueOf(filePointer), Integer.valueOf(status));
+ }
+
+ mis = new MonitoredHttpResponseContentInputStream(httpResponse);
+
+ // If the range request was ignored
+ if (status == HttpURLConnection.HTTP_OK) {
+ final long skipped = mis.skip(filePointer);
+ if (skipped != filePointer) {
+ throw new FileSystemException("vfs.provider.http/get-range.error", fileObject.getName(),
+ Long.valueOf(filePointer), Integer.valueOf(status));
+ }
+ }
+
+ dis = new DataInputStream(new FilterInputStream(mis) {
+ @Override
+ public int read() throws IOException {
+ final int ret = super.read();
+ if (ret > -1) {
+ filePointer++;
+ }
+ return ret;
+ }
+
+ @Override
+ public int read(final byte[] b) throws IOException {
+ final int ret = super.read(b);
+ if (ret > -1) {
+ filePointer += ret;
+ }
+ return ret;
+ }
+
+ @Override
+ public int read(final byte[] b, final int off, final int len) throws IOException {
+ final int ret = super.read(b, off, len);
+ if (ret > -1) {
+ filePointer += ret;
+ }
+ return ret;
+ }
+ });
+
+ return dis;
+ }
+
+ @Override
+ public void close() throws IOException {
+ if (dis != null) {
+ dis.close();
+ dis = null;
+ mis = null;
+ }
+ }
+
+ @Override
+ public long length() throws IOException {
+ return fileObject.getContent().getSize();
+ }
+}
Added: commons/proper/vfs/trunk/commons-vfs2/src/main/java/org/apache/commons/vfs2/provider/http4/MonitoredHttpResponseContentInputStream.java
URL: http://svn.apache.org/viewvc/commons/proper/vfs/trunk/commons-vfs2/src/main/java/org/apache/commons/vfs2/provider/http4/MonitoredHttpResponseContentInputStream.java?rev=1845527&view=auto
==============================================================================
--- commons/proper/vfs/trunk/commons-vfs2/src/main/java/org/apache/commons/vfs2/provider/http4/MonitoredHttpResponseContentInputStream.java (added)
+++ commons/proper/vfs/trunk/commons-vfs2/src/main/java/org/apache/commons/vfs2/provider/http4/MonitoredHttpResponseContentInputStream.java Fri Nov 2 01:53:29 2018
@@ -0,0 +1,44 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.commons.vfs2.provider.http4;
+
+import java.io.IOException;
+
+import org.apache.commons.vfs2.util.MonitorInputStream;
+import org.apache.http.HttpResponse;
+import org.apache.http.client.methods.CloseableHttpResponse;
+
+/**
+ * An InputStream that cleans up the <code>org.apache.http.client.methods.CloseableHttpResponse</code> on close.
+ */
+class MonitoredHttpResponseContentInputStream extends MonitorInputStream {
+
+ private final HttpResponse httpResponse;
+
+ public MonitoredHttpResponseContentInputStream(final HttpResponse httpResponse) throws IOException {
+ super(httpResponse.getEntity().getContent());
+ this.httpResponse = httpResponse;
+ }
+
+ @Override
+ protected void onClose() throws IOException {
+ if (httpResponse instanceof CloseableHttpResponse) {
+ ((CloseableHttpResponse) httpResponse).close();
+ }
+ }
+
+}
Added: commons/proper/vfs/trunk/commons-vfs2/src/main/java/org/apache/commons/vfs2/provider/http4/package.html
URL: http://svn.apache.org/viewvc/commons/proper/vfs/trunk/commons-vfs2/src/main/java/org/apache/commons/vfs2/provider/http4/package.html?rev=1845527&view=auto
==============================================================================
--- commons/proper/vfs/trunk/commons-vfs2/src/main/java/org/apache/commons/vfs2/provider/http4/package.html (added)
+++ commons/proper/vfs/trunk/commons-vfs2/src/main/java/org/apache/commons/vfs2/provider/http4/package.html Fri Nov 2 01:53:29 2018
@@ -0,0 +1,19 @@
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<body>
+<p>The HTTP4 File Provider</p>
+</body>