1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.apache.commons.vfs2.provider.http5;
18
19 import java.io.IOException;
20 import java.io.InputStream;
21 import java.net.URI;
22
23 import org.apache.commons.vfs2.FileContentInfoFactory;
24 import org.apache.commons.vfs2.FileNotFoundException;
25 import org.apache.commons.vfs2.FileSystemException;
26 import org.apache.commons.vfs2.FileSystemOptions;
27 import org.apache.commons.vfs2.FileType;
28 import org.apache.commons.vfs2.RandomAccessContent;
29 import org.apache.commons.vfs2.provider.AbstractFileName;
30 import org.apache.commons.vfs2.provider.AbstractFileObject;
31 import org.apache.commons.vfs2.provider.GenericURLFileName;
32 import org.apache.commons.vfs2.util.RandomAccessMode;
33 import org.apache.hc.client5.http.classic.methods.HttpGet;
34 import org.apache.hc.client5.http.classic.methods.HttpHead;
35 import org.apache.hc.client5.http.classic.methods.HttpUriRequest;
36 import org.apache.hc.client5.http.impl.classic.CloseableHttpClient;
37 import org.apache.hc.client5.http.protocol.HttpClientContext;
38 import org.apache.hc.client5.http.utils.DateUtils;
39 import org.apache.hc.core5.http.ClassicHttpResponse;
40 import org.apache.hc.core5.http.Header;
41 import org.apache.hc.core5.http.HttpHeaders;
42 import org.apache.hc.core5.http.HttpResponse;
43 import org.apache.hc.core5.http.HttpStatus;
44
45
46
47
48
49
50
51 public class Http5FileObject<FS extends Http5FileSystem> extends AbstractFileObject<FS> {
52
53
54
55
56 private final String urlCharset;
57
58
59
60
61
62 private final URI internalURI;
63
64
65
66
67 private HttpResponse lastHeadResponse;
68
69
70
71
72
73
74
75
76 protected Http5FileObject(final AbstractFileName name, final FS fileSystem)
77 throws FileSystemException {
78 this(name, fileSystem, Http5FileSystemConfigBuilder.getInstance());
79 }
80
81
82
83
84
85
86
87
88
89 protected Http5FileObject(final AbstractFileName name, final FS fileSystem,
90 final Http5FileSystemConfigBuilder builder) throws FileSystemException {
91 super(name, fileSystem);
92 final FileSystemOptions fileSystemOptions = fileSystem.getFileSystemOptions();
93 urlCharset = builder.getUrlCharset(fileSystemOptions);
94 final String pathEncoded = ((GenericURLFileName) name).getPathQueryEncoded(getUrlCharset());
95 internalURI = fileSystem.getInternalBaseURI().resolve(pathEncoded);
96 }
97
98 @Override
99 protected void doDetach() throws Exception {
100 lastHeadResponse = null;
101 }
102
103 @Override
104 protected long doGetContentSize() throws Exception {
105 if (lastHeadResponse == null) {
106 return 0L;
107 }
108
109 final Header header = lastHeadResponse.getFirstHeader(HttpHeaders.CONTENT_LENGTH);
110
111 if (header == null) {
112
113 return 0;
114 }
115
116 return Long.parseLong(header.getValue());
117 }
118
119 @Override
120 protected InputStream doGetInputStream(final int bufferSize) throws Exception {
121 final HttpGet getRequest = new HttpGet(getInternalURI());
122 final ClassicHttpResponse httpResponse = executeHttpUriRequest(getRequest);
123 final int status = httpResponse.getCode();
124
125 if (status == HttpStatus.SC_NOT_FOUND) {
126 throw new FileNotFoundException(getName());
127 }
128
129 if (status != HttpStatus.SC_OK) {
130 throw new FileSystemException("vfs.provider.http/get.error", getName(), Integer.valueOf(status));
131 }
132
133 return new MonitoredHttpResponseContentInputStream(httpResponse, bufferSize);
134 }
135
136 @Override
137 protected long doGetLastModifiedTime() throws Exception {
138 FileSystemException.requireNonNull(lastHeadResponse, "vfs.provider.http/last-modified.error", getName());
139
140 final Header header = lastHeadResponse.getFirstHeader("Last-Modified");
141
142 FileSystemException.requireNonNull(header, "vfs.provider.http/last-modified.error", getName());
143
144 return DateUtils.parseStandardDate(header.getValue()).toEpochMilli();
145 }
146
147 @Override
148 protected RandomAccessContent doGetRandomAccessContent(final RandomAccessMode mode) throws Exception {
149 return new Http5RandomAccessContent<>(this, mode);
150 }
151
152 @Override
153 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 ) {
159 return FileType.FILE;
160 }
161 if (status == HttpStatus.SC_NOT_FOUND || status == HttpStatus.SC_GONE) {
162 return FileType.IMAGINARY;
163 }
164 throw new FileSystemException("vfs.provider.http/head.error", getName(), Integer.valueOf(status));
165 }
166
167 @Override
168 protected boolean doIsWriteable() throws Exception {
169 return false;
170 }
171
172 @Override
173 protected String[] doListChildren() throws Exception {
174 throw new UnsupportedOperationException("Not implemented.");
175 }
176
177
178
179
180
181
182
183
184 protected ClassicHttpResponse executeHttpUriRequest(final HttpUriRequest httpRequest) throws IOException {
185 final CloseableHttpClient httpClient = (CloseableHttpClient) getAbstractFileSystem().getHttpClient();
186 final HttpClientContext httpClientContext = getAbstractFileSystem().getHttpClientContext();
187 return httpClient.execute(httpRequest, httpClientContext);
188 }
189
190 @Override
191 protected FileContentInfoFactory getFileContentInfoFactory() {
192 return new Http5FileContentInfoFactory();
193 }
194
195
196
197
198
199
200 protected URI getInternalURI() {
201 return internalURI;
202 }
203
204
205
206
207
208
209
210 HttpResponse getLastHeadResponse() throws IOException {
211 if (lastHeadResponse != null) {
212 return lastHeadResponse;
213 }
214
215 return executeHttpUriRequest(new HttpHead(getInternalURI()));
216 }
217
218
219
220
221
222 protected String getUrlCharset() {
223 return urlCharset;
224 }
225
226 }