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