All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.apache.commons.vfs2.provider.http.HttpFileObject Maven / Gradle / Ivy

There is a newer version: 2.9.0
Show newest version
/*
 * 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.http;

import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;

import org.apache.commons.httpclient.Header;
import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.HttpMethod;
import org.apache.commons.httpclient.URIException;
import org.apache.commons.httpclient.methods.GetMethod;
import org.apache.commons.httpclient.methods.HeadMethod;
import org.apache.commons.httpclient.util.DateUtil;
import org.apache.commons.httpclient.util.URIUtil;
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.URLFileName;
import org.apache.commons.vfs2.util.MonitorInputStream;
import org.apache.commons.vfs2.util.RandomAccessMode;

/**
 * A file object backed by Apache Commons HttpClient.
 * 

* TODO - status codes. *

* * @param An {@link HttpFileSystem} subclass */ public class HttpFileObject extends AbstractFileObject { /** * An InputStream that cleans up the HTTP connection on close. */ static class HttpInputStream extends MonitorInputStream { private final GetMethod method; public HttpInputStream(final GetMethod method) throws IOException { super(method.getResponseBodyAsStream()); this.method = method; } public HttpInputStream(final GetMethod method, final int bufferSize) throws IOException { super(method.getResponseBodyAsStream(), bufferSize); this.method = method; } /** * Called after the stream has been closed. */ @Override protected void onClose() throws IOException { method.releaseConnection(); } } private final String urlCharset; private final String userAgent; private final boolean followRedirect; private HeadMethod method; protected HttpFileObject(final AbstractFileName name, final FS fileSystem) { this(name, fileSystem, HttpFileSystemConfigBuilder.getInstance()); } protected HttpFileObject(final AbstractFileName name, final FS fileSystem, final HttpFileSystemConfigBuilder builder) { super(name, fileSystem); final FileSystemOptions fileSystemOptions = fileSystem.getFileSystemOptions(); urlCharset = builder.getUrlCharset(fileSystemOptions); userAgent = builder.getUserAgent(fileSystemOptions); followRedirect = builder.getFollowRedirect(fileSystemOptions); } /** * Detaches this file object from its file resource. */ @Override protected void doDetach() throws Exception { method = null; } /** * Returns the size of the file content (in bytes). */ @Override protected long doGetContentSize() throws Exception { final Header header = method.getResponseHeader("content-length"); if (header == null) { // Assume 0 content-length return 0; } return Long.parseLong(header.getValue()); } /** * Creates an input stream to read the file content from. Is only called if {@link #doGetType} returns * {@link FileType#FILE}. *

* It is guaranteed that there are no open output streams for this file when this method is called. *

*

* The returned stream does not have to be buffered. *

*/ @Override protected InputStream doGetInputStream(final int bufferSize) throws Exception { final GetMethod getMethod = new GetMethod(); setupMethod(getMethod); final int status = getAbstractFileSystem().getClient().executeMethod(getMethod); if (status == HttpURLConnection.HTTP_NOT_FOUND) { throw new FileNotFoundException(getName()); } if (status != HttpURLConnection.HTTP_OK) { throw new FileSystemException("vfs.provider.http/get.error", getName(), Integer.valueOf(status)); } return new HttpInputStream(getMethod, bufferSize); } /** * Returns the last modified time of this file. *

* This implementation throws an exception. *

*/ @Override protected long doGetLastModifiedTime() throws Exception { final Header header = method.getResponseHeader("last-modified"); FileSystemException.requireNonNull(header, "vfs.provider.http/last-modified.error", getName()); return DateUtil.parseDate(header.getValue()).getTime(); } @Override protected RandomAccessContent doGetRandomAccessContent(final RandomAccessMode mode) throws Exception { return new HttpRandomAccessContent<>(this, mode); } /** * Determines the type of this file. Must not return null. The return value of this method is cached, so the * implementation can be expensive. */ @Override protected FileType doGetType() throws Exception { // Use the HEAD method to probe the file. final int status = this.getHeadMethod().getStatusCode(); if (status == HttpURLConnection.HTTP_OK || status == HttpURLConnection.HTTP_BAD_METHOD /* method is bad, but resource exist */) { return FileType.FILE; } else if (status == HttpURLConnection.HTTP_NOT_FOUND || status == HttpURLConnection.HTTP_GONE) { return FileType.IMAGINARY; } else { throw new FileSystemException("vfs.provider.http/head.error", getName(), Integer.valueOf(status)); } } @Override protected boolean doIsWriteable() throws Exception { return false; } /** * Lists the children of this file. */ @Override protected String[] doListChildren() throws Exception { throw new Exception("Not implemented."); } protected String encodePath(final String decodedPath) throws URIException { return URIUtil.encodePath(decodedPath); } @Override protected FileContentInfoFactory getFileContentInfoFactory() { return new HttpFileContentInfoFactory(); } protected boolean getFollowRedirect() { return followRedirect; } protected String getUserAgent() { return userAgent; } HeadMethod getHeadMethod() throws IOException { if (method != null) { return method; } method = new HeadMethod(); try { setupMethod(method); final HttpClient client = getAbstractFileSystem().getClient(); client.executeMethod(method); } finally { method.releaseConnection(); } return method; } protected String getUrlCharset() { return urlCharset; } /** * Prepares a HttpMethod object. * * @param method The object which gets prepared to access the file object. * @throws FileSystemException if an error occurs. * @throws URIException if path cannot be represented. * @since 2.0 (was package) */ protected void setupMethod(final HttpMethod method) throws FileSystemException, URIException { final String pathEncoded = ((URLFileName) getName()).getPathQueryEncoded(this.getUrlCharset()); method.setPath(pathEncoded); method.setFollowRedirects(this.getFollowRedirect()); method.setRequestHeader("User-Agent", this.getUserAgent()); } /* * protected Map doGetAttributes() throws Exception { TreeMap map = new TreeMap(); * * Header contentType = method.getResponseHeader("content-type"); if (contentType != null) { HeaderElement[] element * = contentType.getValues(); if (element != null && element.length > 0) { map.put("content-type", * element[0].getName()); } } * * map.put("content-encoding", method.getResponseCharSet()); return map; } */ }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy