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