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.DataInputStream;
20 import java.io.FilterInputStream;
21 import java.io.IOException;
22 import java.net.HttpURLConnection;
23
24 import org.apache.commons.vfs2.FileSystemException;
25 import org.apache.commons.vfs2.provider.AbstractRandomAccessStreamContent;
26 import org.apache.commons.vfs2.util.MonitorInputStream;
27 import org.apache.commons.vfs2.util.RandomAccessMode;
28 import org.apache.hc.client5.http.classic.methods.HttpGet;
29 import org.apache.hc.core5.http.ClassicHttpResponse;
30
31
32
33
34
35
36 final class Http5RandomAccessContent<FS extends Http5FileSystem> extends AbstractRandomAccessStreamContent {
37
38 protected long filePointer;
39
40 private final Http5FileObject<FS> fileObject;
41
42 private DataInputStream dataInputStream;
43 private MonitorInputStream monitorInputStream;
44
45 Http5RandomAccessContent(final Http5FileObject<FS> fileObject, final RandomAccessMode mode) {
46 super(mode);
47 this.fileObject = fileObject;
48 }
49
50 @Override
51 public void close() throws IOException {
52 if (dataInputStream != null) {
53 dataInputStream.close();
54 dataInputStream = null;
55 monitorInputStream = null;
56 }
57 }
58
59 @Override
60 protected DataInputStream getDataInputStream() throws IOException {
61 if (dataInputStream != null) {
62 return dataInputStream;
63 }
64
65 final HttpGet httpGet = new HttpGet(fileObject.getInternalURI());
66 httpGet.setHeader("Range", "bytes=" + filePointer + "-");
67 final ClassicHttpResponse httpResponse = fileObject.executeHttpUriRequest(httpGet);
68 final int status = httpResponse.getCode();
69
70 if (status != HttpURLConnection.HTTP_PARTIAL && status != HttpURLConnection.HTTP_OK) {
71 throw new FileSystemException("vfs.provider.http/get-range.error", fileObject.getName(),
72 Long.valueOf(filePointer), Integer.valueOf(status));
73 }
74
75 monitorInputStream = new MonitoredHttpResponseContentInputStream(httpResponse);
76
77
78 if (status == HttpURLConnection.HTTP_OK) {
79 final long skipped = monitorInputStream.skip(filePointer);
80 if (skipped != filePointer) {
81 throw new FileSystemException("vfs.provider.http/get-range.error", fileObject.getName(),
82 Long.valueOf(filePointer), Integer.valueOf(status));
83 }
84 }
85
86 dataInputStream = new DataInputStream(new FilterInputStream(monitorInputStream) {
87 @Override
88 public int read() throws IOException {
89 final int ret = super.read();
90 if (ret > -1) {
91 filePointer++;
92 }
93 return ret;
94 }
95
96 @Override
97 public int read(final byte[] b) throws IOException {
98 final int ret = super.read(b);
99 if (ret > -1) {
100 filePointer += ret;
101 }
102 return ret;
103 }
104
105 @Override
106 public int read(final byte[] b, final int off, final int len) throws IOException {
107 final int ret = super.read(b, off, len);
108 if (ret > -1) {
109 filePointer += ret;
110 }
111 return ret;
112 }
113 });
114
115 return dataInputStream;
116 }
117
118 @Override
119 public long getFilePointer() throws IOException {
120 return filePointer;
121 }
122
123 @Override
124 public long length() throws IOException {
125 return fileObject.getContent().getSize();
126 }
127
128 @Override
129 public void seek(final long pos) throws IOException {
130 if (pos == filePointer) {
131
132 return;
133 }
134
135 if (pos < 0) {
136 throw new FileSystemException("vfs.provider/random-access-invalid-position.error", Long.valueOf(pos));
137 }
138
139 if (dataInputStream != null) {
140 close();
141 }
142
143 filePointer = pos;
144 }
145 }