1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.eclipse.jetty.server;
20
21 import java.util.Enumeration;
22 import java.util.List;
23 import java.util.StringTokenizer;
24
25 import org.eclipse.jetty.util.LazyList;
26 import org.eclipse.jetty.util.log.Log;
27 import org.eclipse.jetty.util.log.Logger;
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50 public class InclusiveByteRange
51 {
52 private static final Logger LOG = Log.getLogger(InclusiveByteRange.class);
53
54 long first = 0;
55 long last = 0;
56
57 public InclusiveByteRange(long first, long last)
58 {
59 this.first = first;
60 this.last = last;
61 }
62
63 public long getFirst()
64 {
65 return first;
66 }
67
68 public long getLast()
69 {
70 return last;
71 }
72
73
74
75
76
77
78
79
80
81 public static List satisfiableRanges(Enumeration headers, long size)
82 {
83 Object satRanges=null;
84
85
86 headers:
87 while (headers.hasMoreElements())
88 {
89 String header = (String) headers.nextElement();
90 StringTokenizer tok = new StringTokenizer(header,"=,",false);
91 String t=null;
92 try
93 {
94
95 while (tok.hasMoreTokens())
96 {
97 try
98 {
99 t = tok.nextToken().trim();
100
101 long first = -1;
102 long last = -1;
103 int d = t.indexOf('-');
104 if (d < 0 || t.indexOf("-",d + 1) >= 0)
105 {
106 if ("bytes".equals(t))
107 continue;
108 LOG.warn("Bad range format: {}",t);
109 continue headers;
110 }
111 else if (d == 0)
112 {
113 if (d + 1 < t.length())
114 last = Long.parseLong(t.substring(d + 1).trim());
115 else
116 {
117 LOG.warn("Bad range format: {}",t);
118 continue;
119 }
120 }
121 else if (d + 1 < t.length())
122 {
123 first = Long.parseLong(t.substring(0,d).trim());
124 last = Long.parseLong(t.substring(d + 1).trim());
125 }
126 else
127 first = Long.parseLong(t.substring(0,d).trim());
128
129 if (first == -1 && last == -1)
130 continue headers;
131
132 if (first != -1 && last != -1 && (first > last))
133 continue headers;
134
135 if (first < size)
136 {
137 InclusiveByteRange range = new InclusiveByteRange(first,last);
138 satRanges = LazyList.add(satRanges,range);
139 }
140 }
141 catch (NumberFormatException e)
142 {
143 LOG.warn("Bad range format: {}",t);
144 LOG.ignore(e);
145 continue;
146 }
147 }
148 }
149 catch(Exception e)
150 {
151 LOG.warn("Bad range format: {}",t);
152 LOG.ignore(e);
153 }
154 }
155 return LazyList.getList(satRanges,true);
156 }
157
158
159 public long getFirst(long size)
160 {
161 if (first<0)
162 {
163 long tf=size-last;
164 if (tf<0)
165 tf=0;
166 return tf;
167 }
168 return first;
169 }
170
171
172 public long getLast(long size)
173 {
174 if (first<0)
175 return size-1;
176
177 if (last<0 ||last>=size)
178 return size-1;
179 return last;
180 }
181
182
183 public long getSize(long size)
184 {
185 return getLast(size)-getFirst(size)+1;
186 }
187
188
189
190 public String toHeaderRangeString(long size)
191 {
192 StringBuilder sb = new StringBuilder(40);
193 sb.append("bytes ");
194 sb.append(getFirst(size));
195 sb.append('-');
196 sb.append(getLast(size));
197 sb.append("/");
198 sb.append(size);
199 return sb.toString();
200 }
201
202
203 public static String to416HeaderRangeString(long size)
204 {
205 StringBuilder sb = new StringBuilder(40);
206 sb.append("bytes */");
207 sb.append(size);
208 return sb.toString();
209 }
210
211
212
213 @Override
214 public String toString()
215 {
216 StringBuilder sb = new StringBuilder(60);
217 sb.append(Long.toString(first));
218 sb.append(":");
219 sb.append(Long.toString(last));
220 return sb.toString();
221 }
222
223
224 }
225
226
227