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 public static List satisfiableRanges(Enumeration headers,long size)
73 {
74 Object satRanges=null;
75
76
77 headers:
78 while (headers.hasMoreElements())
79 {
80 String header = (String) headers.nextElement();
81 StringTokenizer tok = new StringTokenizer(header,"=,",false);
82 String t=null;
83 try
84 {
85
86 while (tok.hasMoreTokens())
87 {
88 t=tok.nextToken().trim();
89
90 long first = -1;
91 long last = -1;
92 int d=t.indexOf('-');
93 if (d<0 || t.indexOf("-",d+1)>=0)
94 {
95 if ("bytes".equals(t))
96 continue;
97 Log.warn("Bad range format: {}",t);
98 continue headers;
99 }
100 else if (d==0)
101 {
102 if (d+1<t.length())
103 last = Long.parseLong(t.substring(d+1).trim());
104 else
105 {
106 Log.warn("Bad range format: {}",t);
107 continue headers;
108 }
109 }
110 else if (d+1<t.length())
111 {
112 first = Long.parseLong(t.substring(0,d).trim());
113 last = Long.parseLong(t.substring(d+1).trim());
114 }
115 else
116 first = Long.parseLong(t.substring(0,d).trim());
117
118 if (first == -1 && last == -1)
119 continue headers;
120
121 if (first != -1 && last != -1 && (first > last))
122 continue headers;
123
124 if (first<size)
125 {
126 InclusiveByteRange range = new
127 InclusiveByteRange(first, last);
128 satRanges=LazyList.add(satRanges,range);
129 }
130 }
131 }
132 catch(Exception e)
133 {
134 Log.warn("Bad range format: "+t);
135 Log.ignore(e);
136 }
137 }
138 return LazyList.getList(satRanges,true);
139 }
140
141
142 public long getFirst(long size)
143 {
144 if (first<0)
145 {
146 long tf=size-last;
147 if (tf<0)
148 tf=0;
149 return tf;
150 }
151 return first;
152 }
153
154
155 public long getLast(long size)
156 {
157 if (first<0)
158 return size-1;
159
160 if (last<0 ||last>=size)
161 return size-1;
162 return last;
163 }
164
165
166 public long getSize(long size)
167 {
168 return getLast(size)-getFirst(size)+1;
169 }
170
171
172
173 public String toHeaderRangeString(long size)
174 {
175 StringBuffer sb = new StringBuffer(40);
176 sb.append("bytes ");
177 sb.append(getFirst(size));
178 sb.append('-');
179 sb.append(getLast(size));
180 sb.append("/");
181 sb.append(size);
182 return sb.toString();
183 }
184
185
186 public static String to416HeaderRangeString(long size)
187 {
188 StringBuffer sb = new StringBuffer(40);
189 sb.append("bytes */");
190 sb.append(size);
191 return sb.toString();
192 }
193
194
195
196 public String toString()
197 {
198 StringBuffer sb = new StringBuffer(60);
199 sb.append(Long.toString(first));
200 sb.append(":");
201 sb.append(Long.toString(last));
202 return sb.toString();
203 }
204
205
206 }
207
208
209