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, 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 InclusiveByteRange range = new InclusiveByteRange(first,last);
130 satRanges = LazyList.add(satRanges,range);
131 }
132 }
133 catch (NumberFormatException e)
134 {
135 Log.warn("Bad range format: {}",t);
136 Log.ignore(e);
137 continue;
138 }
139 }
140 }
141 catch(Exception e)
142 {
143 Log.warn("Bad range format: {}",t);
144 Log.ignore(e);
145 }
146 }
147 return LazyList.getList(satRanges,true);
148 }
149
150
151 public long getFirst(long size)
152 {
153 if (first<0)
154 {
155 long tf=size-last;
156 if (tf<0)
157 tf=0;
158 return tf;
159 }
160 return first;
161 }
162
163
164 public long getLast(long size)
165 {
166 if (first<0)
167 return size-1;
168
169 if (last<0 ||last>=size)
170 return size-1;
171 return last;
172 }
173
174
175 public long getSize(long size)
176 {
177 return getLast(size)-getFirst(size)+1;
178 }
179
180
181
182 public String toHeaderRangeString(long size)
183 {
184 StringBuilder sb = new StringBuilder(40);
185 sb.append("bytes ");
186 sb.append(getFirst(size));
187 sb.append('-');
188 sb.append(getLast(size));
189 sb.append("/");
190 sb.append(size);
191 return sb.toString();
192 }
193
194
195 public static String to416HeaderRangeString(long size)
196 {
197 StringBuilder sb = new StringBuilder(40);
198 sb.append("bytes */");
199 sb.append(size);
200 return sb.toString();
201 }
202
203
204
205 @Override
206 public String toString()
207 {
208 StringBuilder sb = new StringBuilder(60);
209 sb.append(Long.toString(first));
210 sb.append(":");
211 sb.append(Long.toString(last));
212 return sb.toString();
213 }
214
215
216 }
217
218
219