Skip to content

Commit 498a80d

Browse files
committed
org.apache.commons.vfs2.provider.http5.Http5FileObject.doGetInputStream(int)
now closes its ClassicHttpResponse on a non-200 OK response
1 parent 442baff commit 498a80d

File tree

2 files changed

+22
-29
lines changed

2 files changed

+22
-29
lines changed

commons-vfs2/src/main/java/org/apache/commons/vfs2/provider/http5/Http5FileObject.java

Lines changed: 21 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
import java.io.InputStream;
2121
import java.net.URI;
2222

23+
import org.apache.commons.io.IOUtils;
2324
import org.apache.commons.vfs2.FileContentInfoFactory;
2425
import org.apache.commons.vfs2.FileNotFoundException;
2526
import org.apache.commons.vfs2.FileSystemException;
@@ -39,7 +40,6 @@
3940
import org.apache.hc.core5.http.ClassicHttpResponse;
4041
import org.apache.hc.core5.http.Header;
4142
import org.apache.hc.core5.http.HttpHeaders;
42-
import org.apache.hc.core5.http.HttpResponse;
4343
import org.apache.hc.core5.http.HttpStatus;
4444

4545
/**
@@ -62,9 +62,9 @@ public class Http5FileObject<FS extends Http5FileSystem> extends AbstractFileObj
6262
private final URI internalURI;
6363

6464
/**
65-
* The last executed HEAD {@code HttpResponse} object.
65+
* The last executed HEAD {@code ClassicHttpResponse} object.
6666
*/
67-
private HttpResponse lastHeadResponse;
67+
private ClassicHttpResponse lastHeadResponse;
6868

6969
/**
7070
* Constructs {@code Http4FileObject}.
@@ -73,8 +73,7 @@ public class Http5FileObject<FS extends Http5FileSystem> extends AbstractFileObj
7373
* @param fileSystem file system
7474
* @throws FileSystemException if any error occurs
7575
*/
76-
protected Http5FileObject(final AbstractFileName name, final FS fileSystem)
77-
throws FileSystemException {
76+
protected Http5FileObject(final AbstractFileName name, final FS fileSystem) throws FileSystemException {
7877
this(name, fileSystem, Http5FileSystemConfigBuilder.getInstance());
7978
}
8079

@@ -105,42 +104,36 @@ protected long doGetContentSize() throws Exception {
105104
if (lastHeadResponse == null) {
106105
return 0L;
107106
}
108-
109107
final Header header = lastHeadResponse.getFirstHeader(HttpHeaders.CONTENT_LENGTH);
110-
111108
if (header == null) {
112109
// Assume 0 content-length
113110
return 0;
114111
}
115-
116112
return Long.parseLong(header.getValue());
117113
}
118114

119115
@Override
120116
protected InputStream doGetInputStream(final int bufferSize) throws Exception {
121117
final HttpGet getRequest = new HttpGet(getInternalURI());
118+
@SuppressWarnings("resource") // Caller closes
122119
final ClassicHttpResponse httpResponse = executeHttpUriRequest(getRequest);
123120
final int status = httpResponse.getCode();
124-
125121
if (status == HttpStatus.SC_NOT_FOUND) {
122+
IOUtils.closeQuietly(httpResponse);
126123
throw new FileNotFoundException(getName());
127124
}
128-
129125
if (status != HttpStatus.SC_OK) {
126+
IOUtils.closeQuietly(httpResponse);
130127
throw new FileSystemException("vfs.provider.http/get.error", getName(), Integer.valueOf(status));
131128
}
132-
133129
return new MonitoredHttpResponseContentInputStream(httpResponse, bufferSize);
134130
}
135131

136132
@Override
137133
protected long doGetLastModifiedTime() throws Exception {
138134
FileSystemException.requireNonNull(lastHeadResponse, "vfs.provider.http/last-modified.error", getName());
139-
140135
final Header header = lastHeadResponse.getFirstHeader("Last-Modified");
141-
142136
FileSystemException.requireNonNull(header, "vfs.provider.http/last-modified.error", getName());
143-
144137
return DateUtils.parseStandardDate(header.getValue()).toEpochMilli();
145138
}
146139

@@ -151,17 +144,16 @@ protected RandomAccessContent doGetRandomAccessContent(final RandomAccessMode mo
151144

152145
@Override
153146
protected FileType doGetType() throws Exception {
154-
lastHeadResponse = executeHttpUriRequest(new HttpHead(getInternalURI()));
155-
final int status = lastHeadResponse.getCode();
156-
157-
if (status == HttpStatus.SC_OK
158-
|| status == HttpStatus.SC_METHOD_NOT_ALLOWED /* method is not allowed, but resource exist */) {
159-
return FileType.FILE;
160-
}
161-
if (status == HttpStatus.SC_NOT_FOUND || status == HttpStatus.SC_GONE) {
162-
return FileType.IMAGINARY;
147+
try (ClassicHttpResponse response = lastHeadResponse = executeHttpUriRequest(new HttpHead(getInternalURI()))) {
148+
final int status = response.getCode();
149+
if (status == HttpStatus.SC_OK || status == HttpStatus.SC_METHOD_NOT_ALLOWED /* method is not allowed, but resource exist */) {
150+
return FileType.FILE;
151+
}
152+
if (status == HttpStatus.SC_NOT_FOUND || status == HttpStatus.SC_GONE) {
153+
return FileType.IMAGINARY;
154+
}
155+
throw new FileSystemException("vfs.provider.http/head.error", getName(), Integer.valueOf(status));
163156
}
164-
throw new FileSystemException("vfs.provider.http/head.error", getName(), Integer.valueOf(status));
165157
}
166158

167159
@Override
@@ -175,15 +167,16 @@ protected String[] doListChildren() throws Exception {
175167
}
176168

177169
/**
178-
* Execute the request using the given {@code httpRequest} and return a {@code ClassicHttpResponse} from the execution.
170+
* Executes the request using the given {@code httpRequest} and return a {@code ClassicHttpResponse} from the execution.
179171
*
180172
* @param httpRequest {@code HttpUriRequest} object
181173
* @return {@code ClassicHttpResponse} from the execution
182174
* @throws IOException if IO error occurs
183175
*/
184176
protected ClassicHttpResponse executeHttpUriRequest(final HttpUriRequest httpRequest) throws IOException {
185-
final CloseableHttpClient httpClient = (CloseableHttpClient) getAbstractFileSystem().getHttpClient();
186-
final HttpClientContext httpClientContext = getAbstractFileSystem().getHttpClientContext();
177+
final FS abstractFileSystem = getAbstractFileSystem();
178+
final CloseableHttpClient httpClient = (CloseableHttpClient) abstractFileSystem.getHttpClient();
179+
final HttpClientContext httpClientContext = abstractFileSystem.getHttpClientContext();
187180
return httpClient.execute(httpRequest, httpClientContext);
188181
}
189182

@@ -207,11 +200,10 @@ protected URI getInternalURI() {
207200
* @return the last executed HEAD {@code HttpResponse} object
208201
* @throws IOException if IO error occurs
209202
*/
210-
HttpResponse getLastHeadResponse() throws IOException {
203+
ClassicHttpResponse getLastHeadResponse() throws IOException {
211204
if (lastHeadResponse != null) {
212205
return lastHeadResponse;
213206
}
214-
215207
return executeHttpUriRequest(new HttpHead(getInternalURI()));
216208
}
217209

src/changes/changes.xml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@ The <action> type attribute can be add,update,fix,remove.
5353
<action dev="ggregory" type="fix" due-to="Anthony Goubard">Improved performance of UriParser#extractScheme #614.</action>
5454
<action dev="ggregory" type="fix" due-to="Andrey Turbanov, Gary Gregory">Fix Javadoc for ResourceFileSystemConfigBuilder #695.</action>
5555
<action dev="ggregory" type="fix" due-to="Gary Gregory">Make sure org.apache.commons.vfs2.provider.http5.MonitoredHttpResponseContentInputStream.onClose() always closes its ClassicHttpResponse.</action>
56+
<action dev="ggregory" type="fix" due-to="Gary Gregory, WANGWEI">org.apache.commons.vfs2.provider.http5.Http5FileObject.doGetInputStream(int) now closes its ClassicHttpResponse on a non-200 OK response.</action>
5657
<!-- ADD -->
5758
<action dev="ggregory" type="add" due-to="Gary Gregory">Add org.apache.commons.vfs2.provider.ftp.FTPClientWrapper.sendOptions(String, String).</action>
5859
<action dev="ggregory" type="add" due-to="Gary Gregory">Add FtpFileSystemConfigBuilder.getControlEncodingCharset(FileSystemOptions) and deprecate getControlEncoding(FileSystemOptions).</action>

0 commit comments

Comments
 (0)