1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.apache.commons.vfs2.provider.http;
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.httpclient.methods.GetMethod;
25 import org.apache.commons.vfs2.FileSystemException;
26 import org.apache.commons.vfs2.provider.AbstractRandomAccessStreamContent;
27 import org.apache.commons.vfs2.util.MonitorInputStream;
28 import org.apache.commons.vfs2.util.RandomAccessMode;
29
30
31
32
33 final class HttpRandomAccessContent<FS extends HttpFileSystem> extends AbstractRandomAccessStreamContent {
34
35 protected long filePointer;
36
37 private final HttpFileObject<FS> fileObject;
38 private final HttpFileSystem fileSystem;
39
40 private DataInputStream dataInputStream;
41 private MonitorInputStream monitorInputStream;
42
43 HttpRandomAccessContent(final HttpFileObject<FS> fileObject, final RandomAccessMode mode) {
44 super(mode);
45
46 this.fileObject = fileObject;
47 fileSystem = (HttpFileSystem) this.fileObject.getFileSystem();
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 GetMethod getMethod = new GetMethod();
66 fileObject.setupMethod(getMethod);
67 getMethod.setRequestHeader("Range", "bytes=" + filePointer + "-");
68 final int status = fileSystem.getClient().executeMethod(getMethod);
69 if (status != HttpURLConnection.HTTP_PARTIAL && status != HttpURLConnection.HTTP_OK) {
70 throw new FileSystemException("vfs.provider.http/get-range.error", fileObject.getName(),
71 Long.valueOf(filePointer), Integer.valueOf(status));
72 }
73
74 monitorInputStream = new HttpFileObject.HttpInputStream(getMethod);
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 dataInputStream = new DataInputStream(new FilterInputStream(monitorInputStream) {
84 @Override
85 public int read() throws IOException {
86 final int ret = super.read();
87 if (ret > -1) {
88 filePointer++;
89 }
90 return ret;
91 }
92
93 @Override
94 public int read(final byte[] b) throws IOException {
95 final int ret = super.read(b);
96 if (ret > -1) {
97 filePointer += ret;
98 }
99 return ret;
100 }
101
102 @Override
103 public int read(final byte[] b, final int off, final int len) throws IOException {
104 final int ret = super.read(b, off, len);
105 if (ret > -1) {
106 filePointer += ret;
107 }
108 return ret;
109 }
110 });
111
112 return dataInputStream;
113 }
114
115 @Override
116 public long getFilePointer() throws IOException {
117 return filePointer;
118 }
119
120 @Override
121 public long length() throws IOException {
122 return fileObject.getContent().getSize();
123 }
124
125 @Override
126 public void seek(final long pos) throws IOException {
127 if (pos == filePointer) {
128
129 return;
130 }
131
132 if (pos < 0) {
133 throw new FileSystemException("vfs.provider/random-access-invalid-position.error", Long.valueOf(pos));
134 }
135 if (dataInputStream != null) {
136 close();
137 }
138
139 filePointer = pos;
140 }
141 }