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