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