103928aee4356845252ac6b662d5c72c29903813eJake Slack// 203928aee4356845252ac6b662d5c72c29903813eJake Slack// ======================================================================== 303928aee4356845252ac6b662d5c72c29903813eJake Slack// Copyright (c) 1995-2014 Mort Bay Consulting Pty. Ltd. 403928aee4356845252ac6b662d5c72c29903813eJake Slack// ------------------------------------------------------------------------ 503928aee4356845252ac6b662d5c72c29903813eJake Slack// All rights reserved. This program and the accompanying materials 603928aee4356845252ac6b662d5c72c29903813eJake Slack// are made available under the terms of the Eclipse Public License v1.0 703928aee4356845252ac6b662d5c72c29903813eJake Slack// and Apache License v2.0 which accompanies this distribution. 803928aee4356845252ac6b662d5c72c29903813eJake Slack// 903928aee4356845252ac6b662d5c72c29903813eJake Slack// The Eclipse Public License is available at 1003928aee4356845252ac6b662d5c72c29903813eJake Slack// http://www.eclipse.org/legal/epl-v10.html 1103928aee4356845252ac6b662d5c72c29903813eJake Slack// 1203928aee4356845252ac6b662d5c72c29903813eJake Slack// The Apache License v2.0 is available at 1303928aee4356845252ac6b662d5c72c29903813eJake Slack// http://www.opensource.org/licenses/apache2.0.php 1403928aee4356845252ac6b662d5c72c29903813eJake Slack// 1503928aee4356845252ac6b662d5c72c29903813eJake Slack// You may elect to redistribute this code under either of these licenses. 1603928aee4356845252ac6b662d5c72c29903813eJake Slack// ======================================================================== 1703928aee4356845252ac6b662d5c72c29903813eJake Slack// 1803928aee4356845252ac6b662d5c72c29903813eJake Slack 1903928aee4356845252ac6b662d5c72c29903813eJake Slackpackage org.eclipse.jetty.server; 2003928aee4356845252ac6b662d5c72c29903813eJake Slack 2103928aee4356845252ac6b662d5c72c29903813eJake Slackimport java.util.Enumeration; 2203928aee4356845252ac6b662d5c72c29903813eJake Slackimport java.util.List; 2303928aee4356845252ac6b662d5c72c29903813eJake Slackimport java.util.StringTokenizer; 2403928aee4356845252ac6b662d5c72c29903813eJake Slack 2503928aee4356845252ac6b662d5c72c29903813eJake Slackimport org.eclipse.jetty.util.LazyList; 2603928aee4356845252ac6b662d5c72c29903813eJake Slackimport org.eclipse.jetty.util.log.Log; 2703928aee4356845252ac6b662d5c72c29903813eJake Slackimport org.eclipse.jetty.util.log.Logger; 2803928aee4356845252ac6b662d5c72c29903813eJake Slack 2903928aee4356845252ac6b662d5c72c29903813eJake Slack/* ------------------------------------------------------------ */ 3003928aee4356845252ac6b662d5c72c29903813eJake Slack/** Byte range inclusive of end points. 3103928aee4356845252ac6b662d5c72c29903813eJake Slack * <PRE> 3203928aee4356845252ac6b662d5c72c29903813eJake Slack * 3303928aee4356845252ac6b662d5c72c29903813eJake Slack * parses the following types of byte ranges: 3403928aee4356845252ac6b662d5c72c29903813eJake Slack * 3503928aee4356845252ac6b662d5c72c29903813eJake Slack * bytes=100-499 3603928aee4356845252ac6b662d5c72c29903813eJake Slack * bytes=-300 3703928aee4356845252ac6b662d5c72c29903813eJake Slack * bytes=100- 3803928aee4356845252ac6b662d5c72c29903813eJake Slack * bytes=1-2,2-3,6-,-2 3903928aee4356845252ac6b662d5c72c29903813eJake Slack * 4003928aee4356845252ac6b662d5c72c29903813eJake Slack * given an entity length, converts range to string 4103928aee4356845252ac6b662d5c72c29903813eJake Slack * 4203928aee4356845252ac6b662d5c72c29903813eJake Slack * bytes 100-499/500 4303928aee4356845252ac6b662d5c72c29903813eJake Slack * 4403928aee4356845252ac6b662d5c72c29903813eJake Slack * </PRE> 4503928aee4356845252ac6b662d5c72c29903813eJake Slack * 4603928aee4356845252ac6b662d5c72c29903813eJake Slack * Based on RFC2616 3.12, 14.16, 14.35.1, 14.35.2 4703928aee4356845252ac6b662d5c72c29903813eJake Slack * @version $version$ 4803928aee4356845252ac6b662d5c72c29903813eJake Slack * 4903928aee4356845252ac6b662d5c72c29903813eJake Slack */ 5003928aee4356845252ac6b662d5c72c29903813eJake Slackpublic class InclusiveByteRange 5103928aee4356845252ac6b662d5c72c29903813eJake Slack{ 5203928aee4356845252ac6b662d5c72c29903813eJake Slack private static final Logger LOG = Log.getLogger(InclusiveByteRange.class); 5303928aee4356845252ac6b662d5c72c29903813eJake Slack 5403928aee4356845252ac6b662d5c72c29903813eJake Slack long first = 0; 5503928aee4356845252ac6b662d5c72c29903813eJake Slack long last = 0; 5603928aee4356845252ac6b662d5c72c29903813eJake Slack 5703928aee4356845252ac6b662d5c72c29903813eJake Slack public InclusiveByteRange(long first, long last) 5803928aee4356845252ac6b662d5c72c29903813eJake Slack { 5903928aee4356845252ac6b662d5c72c29903813eJake Slack this.first = first; 6003928aee4356845252ac6b662d5c72c29903813eJake Slack this.last = last; 6103928aee4356845252ac6b662d5c72c29903813eJake Slack } 6203928aee4356845252ac6b662d5c72c29903813eJake Slack 6303928aee4356845252ac6b662d5c72c29903813eJake Slack public long getFirst() 6403928aee4356845252ac6b662d5c72c29903813eJake Slack { 6503928aee4356845252ac6b662d5c72c29903813eJake Slack return first; 6603928aee4356845252ac6b662d5c72c29903813eJake Slack } 6703928aee4356845252ac6b662d5c72c29903813eJake Slack 6803928aee4356845252ac6b662d5c72c29903813eJake Slack public long getLast() 6903928aee4356845252ac6b662d5c72c29903813eJake Slack { 7003928aee4356845252ac6b662d5c72c29903813eJake Slack return last; 7103928aee4356845252ac6b662d5c72c29903813eJake Slack } 7203928aee4356845252ac6b662d5c72c29903813eJake Slack 7303928aee4356845252ac6b662d5c72c29903813eJake Slack 7403928aee4356845252ac6b662d5c72c29903813eJake Slack 7503928aee4356845252ac6b662d5c72c29903813eJake Slack /* ------------------------------------------------------------ */ 7603928aee4356845252ac6b662d5c72c29903813eJake Slack /** 7703928aee4356845252ac6b662d5c72c29903813eJake Slack * @param headers Enumeration of Range header fields. 7803928aee4356845252ac6b662d5c72c29903813eJake Slack * @param size Size of the resource. 7903928aee4356845252ac6b662d5c72c29903813eJake Slack * @return LazyList of satisfiable ranges 8003928aee4356845252ac6b662d5c72c29903813eJake Slack */ 8103928aee4356845252ac6b662d5c72c29903813eJake Slack public static List satisfiableRanges(Enumeration headers, long size) 8203928aee4356845252ac6b662d5c72c29903813eJake Slack { 8303928aee4356845252ac6b662d5c72c29903813eJake Slack Object satRanges=null; 8403928aee4356845252ac6b662d5c72c29903813eJake Slack 8503928aee4356845252ac6b662d5c72c29903813eJake Slack // walk through all Range headers 8603928aee4356845252ac6b662d5c72c29903813eJake Slack headers: 8703928aee4356845252ac6b662d5c72c29903813eJake Slack while (headers.hasMoreElements()) 8803928aee4356845252ac6b662d5c72c29903813eJake Slack { 8903928aee4356845252ac6b662d5c72c29903813eJake Slack String header = (String) headers.nextElement(); 9003928aee4356845252ac6b662d5c72c29903813eJake Slack StringTokenizer tok = new StringTokenizer(header,"=,",false); 9103928aee4356845252ac6b662d5c72c29903813eJake Slack String t=null; 9203928aee4356845252ac6b662d5c72c29903813eJake Slack try 9303928aee4356845252ac6b662d5c72c29903813eJake Slack { 9403928aee4356845252ac6b662d5c72c29903813eJake Slack // read all byte ranges for this header 9503928aee4356845252ac6b662d5c72c29903813eJake Slack while (tok.hasMoreTokens()) 9603928aee4356845252ac6b662d5c72c29903813eJake Slack { 9703928aee4356845252ac6b662d5c72c29903813eJake Slack try 9803928aee4356845252ac6b662d5c72c29903813eJake Slack { 9903928aee4356845252ac6b662d5c72c29903813eJake Slack t = tok.nextToken().trim(); 10003928aee4356845252ac6b662d5c72c29903813eJake Slack 10103928aee4356845252ac6b662d5c72c29903813eJake Slack long first = -1; 10203928aee4356845252ac6b662d5c72c29903813eJake Slack long last = -1; 10303928aee4356845252ac6b662d5c72c29903813eJake Slack int d = t.indexOf('-'); 10403928aee4356845252ac6b662d5c72c29903813eJake Slack if (d < 0 || t.indexOf("-",d + 1) >= 0) 10503928aee4356845252ac6b662d5c72c29903813eJake Slack { 10603928aee4356845252ac6b662d5c72c29903813eJake Slack if ("bytes".equals(t)) 10703928aee4356845252ac6b662d5c72c29903813eJake Slack continue; 10803928aee4356845252ac6b662d5c72c29903813eJake Slack LOG.warn("Bad range format: {}",t); 10903928aee4356845252ac6b662d5c72c29903813eJake Slack continue headers; 11003928aee4356845252ac6b662d5c72c29903813eJake Slack } 11103928aee4356845252ac6b662d5c72c29903813eJake Slack else if (d == 0) 11203928aee4356845252ac6b662d5c72c29903813eJake Slack { 11303928aee4356845252ac6b662d5c72c29903813eJake Slack if (d + 1 < t.length()) 11403928aee4356845252ac6b662d5c72c29903813eJake Slack last = Long.parseLong(t.substring(d + 1).trim()); 11503928aee4356845252ac6b662d5c72c29903813eJake Slack else 11603928aee4356845252ac6b662d5c72c29903813eJake Slack { 11703928aee4356845252ac6b662d5c72c29903813eJake Slack LOG.warn("Bad range format: {}",t); 11803928aee4356845252ac6b662d5c72c29903813eJake Slack continue; 11903928aee4356845252ac6b662d5c72c29903813eJake Slack } 12003928aee4356845252ac6b662d5c72c29903813eJake Slack } 12103928aee4356845252ac6b662d5c72c29903813eJake Slack else if (d + 1 < t.length()) 12203928aee4356845252ac6b662d5c72c29903813eJake Slack { 12303928aee4356845252ac6b662d5c72c29903813eJake Slack first = Long.parseLong(t.substring(0,d).trim()); 12403928aee4356845252ac6b662d5c72c29903813eJake Slack last = Long.parseLong(t.substring(d + 1).trim()); 12503928aee4356845252ac6b662d5c72c29903813eJake Slack } 12603928aee4356845252ac6b662d5c72c29903813eJake Slack else 12703928aee4356845252ac6b662d5c72c29903813eJake Slack first = Long.parseLong(t.substring(0,d).trim()); 12803928aee4356845252ac6b662d5c72c29903813eJake Slack 12903928aee4356845252ac6b662d5c72c29903813eJake Slack if (first == -1 && last == -1) 13003928aee4356845252ac6b662d5c72c29903813eJake Slack continue headers; 13103928aee4356845252ac6b662d5c72c29903813eJake Slack 13203928aee4356845252ac6b662d5c72c29903813eJake Slack if (first != -1 && last != -1 && (first > last)) 13303928aee4356845252ac6b662d5c72c29903813eJake Slack continue headers; 13403928aee4356845252ac6b662d5c72c29903813eJake Slack 13503928aee4356845252ac6b662d5c72c29903813eJake Slack if (first < size) 13603928aee4356845252ac6b662d5c72c29903813eJake Slack { 13703928aee4356845252ac6b662d5c72c29903813eJake Slack InclusiveByteRange range = new InclusiveByteRange(first,last); 13803928aee4356845252ac6b662d5c72c29903813eJake Slack satRanges = LazyList.add(satRanges,range); 13903928aee4356845252ac6b662d5c72c29903813eJake Slack } 14003928aee4356845252ac6b662d5c72c29903813eJake Slack } 14103928aee4356845252ac6b662d5c72c29903813eJake Slack catch (NumberFormatException e) 14203928aee4356845252ac6b662d5c72c29903813eJake Slack { 14303928aee4356845252ac6b662d5c72c29903813eJake Slack LOG.warn("Bad range format: {}",t); 14403928aee4356845252ac6b662d5c72c29903813eJake Slack LOG.ignore(e); 14503928aee4356845252ac6b662d5c72c29903813eJake Slack continue; 14603928aee4356845252ac6b662d5c72c29903813eJake Slack } 14703928aee4356845252ac6b662d5c72c29903813eJake Slack } 14803928aee4356845252ac6b662d5c72c29903813eJake Slack } 14903928aee4356845252ac6b662d5c72c29903813eJake Slack catch(Exception e) 15003928aee4356845252ac6b662d5c72c29903813eJake Slack { 15103928aee4356845252ac6b662d5c72c29903813eJake Slack LOG.warn("Bad range format: {}",t); 15203928aee4356845252ac6b662d5c72c29903813eJake Slack LOG.ignore(e); 15303928aee4356845252ac6b662d5c72c29903813eJake Slack } 15403928aee4356845252ac6b662d5c72c29903813eJake Slack } 15503928aee4356845252ac6b662d5c72c29903813eJake Slack return LazyList.getList(satRanges,true); 15603928aee4356845252ac6b662d5c72c29903813eJake Slack } 15703928aee4356845252ac6b662d5c72c29903813eJake Slack 15803928aee4356845252ac6b662d5c72c29903813eJake Slack /* ------------------------------------------------------------ */ 15903928aee4356845252ac6b662d5c72c29903813eJake Slack public long getFirst(long size) 16003928aee4356845252ac6b662d5c72c29903813eJake Slack { 16103928aee4356845252ac6b662d5c72c29903813eJake Slack if (first<0) 16203928aee4356845252ac6b662d5c72c29903813eJake Slack { 16303928aee4356845252ac6b662d5c72c29903813eJake Slack long tf=size-last; 16403928aee4356845252ac6b662d5c72c29903813eJake Slack if (tf<0) 16503928aee4356845252ac6b662d5c72c29903813eJake Slack tf=0; 16603928aee4356845252ac6b662d5c72c29903813eJake Slack return tf; 16703928aee4356845252ac6b662d5c72c29903813eJake Slack } 16803928aee4356845252ac6b662d5c72c29903813eJake Slack return first; 16903928aee4356845252ac6b662d5c72c29903813eJake Slack } 17003928aee4356845252ac6b662d5c72c29903813eJake Slack 17103928aee4356845252ac6b662d5c72c29903813eJake Slack /* ------------------------------------------------------------ */ 17203928aee4356845252ac6b662d5c72c29903813eJake Slack public long getLast(long size) 17303928aee4356845252ac6b662d5c72c29903813eJake Slack { 17403928aee4356845252ac6b662d5c72c29903813eJake Slack if (first<0) 17503928aee4356845252ac6b662d5c72c29903813eJake Slack return size-1; 17603928aee4356845252ac6b662d5c72c29903813eJake Slack 17703928aee4356845252ac6b662d5c72c29903813eJake Slack if (last<0 ||last>=size) 17803928aee4356845252ac6b662d5c72c29903813eJake Slack return size-1; 17903928aee4356845252ac6b662d5c72c29903813eJake Slack return last; 18003928aee4356845252ac6b662d5c72c29903813eJake Slack } 18103928aee4356845252ac6b662d5c72c29903813eJake Slack 18203928aee4356845252ac6b662d5c72c29903813eJake Slack /* ------------------------------------------------------------ */ 18303928aee4356845252ac6b662d5c72c29903813eJake Slack public long getSize(long size) 18403928aee4356845252ac6b662d5c72c29903813eJake Slack { 18503928aee4356845252ac6b662d5c72c29903813eJake Slack return getLast(size)-getFirst(size)+1; 18603928aee4356845252ac6b662d5c72c29903813eJake Slack } 18703928aee4356845252ac6b662d5c72c29903813eJake Slack 18803928aee4356845252ac6b662d5c72c29903813eJake Slack 18903928aee4356845252ac6b662d5c72c29903813eJake Slack /* ------------------------------------------------------------ */ 19003928aee4356845252ac6b662d5c72c29903813eJake Slack public String toHeaderRangeString(long size) 19103928aee4356845252ac6b662d5c72c29903813eJake Slack { 19203928aee4356845252ac6b662d5c72c29903813eJake Slack StringBuilder sb = new StringBuilder(40); 19303928aee4356845252ac6b662d5c72c29903813eJake Slack sb.append("bytes "); 19403928aee4356845252ac6b662d5c72c29903813eJake Slack sb.append(getFirst(size)); 19503928aee4356845252ac6b662d5c72c29903813eJake Slack sb.append('-'); 19603928aee4356845252ac6b662d5c72c29903813eJake Slack sb.append(getLast(size)); 19703928aee4356845252ac6b662d5c72c29903813eJake Slack sb.append("/"); 19803928aee4356845252ac6b662d5c72c29903813eJake Slack sb.append(size); 19903928aee4356845252ac6b662d5c72c29903813eJake Slack return sb.toString(); 20003928aee4356845252ac6b662d5c72c29903813eJake Slack } 20103928aee4356845252ac6b662d5c72c29903813eJake Slack 20203928aee4356845252ac6b662d5c72c29903813eJake Slack /* ------------------------------------------------------------ */ 20303928aee4356845252ac6b662d5c72c29903813eJake Slack public static String to416HeaderRangeString(long size) 20403928aee4356845252ac6b662d5c72c29903813eJake Slack { 20503928aee4356845252ac6b662d5c72c29903813eJake Slack StringBuilder sb = new StringBuilder(40); 20603928aee4356845252ac6b662d5c72c29903813eJake Slack sb.append("bytes */"); 20703928aee4356845252ac6b662d5c72c29903813eJake Slack sb.append(size); 20803928aee4356845252ac6b662d5c72c29903813eJake Slack return sb.toString(); 20903928aee4356845252ac6b662d5c72c29903813eJake Slack } 21003928aee4356845252ac6b662d5c72c29903813eJake Slack 21103928aee4356845252ac6b662d5c72c29903813eJake Slack 21203928aee4356845252ac6b662d5c72c29903813eJake Slack /* ------------------------------------------------------------ */ 21303928aee4356845252ac6b662d5c72c29903813eJake Slack @Override 21403928aee4356845252ac6b662d5c72c29903813eJake Slack public String toString() 21503928aee4356845252ac6b662d5c72c29903813eJake Slack { 21603928aee4356845252ac6b662d5c72c29903813eJake Slack StringBuilder sb = new StringBuilder(60); 21703928aee4356845252ac6b662d5c72c29903813eJake Slack sb.append(Long.toString(first)); 21803928aee4356845252ac6b662d5c72c29903813eJake Slack sb.append(":"); 21903928aee4356845252ac6b662d5c72c29903813eJake Slack sb.append(Long.toString(last)); 22003928aee4356845252ac6b662d5c72c29903813eJake Slack return sb.toString(); 22103928aee4356845252ac6b662d5c72c29903813eJake Slack } 22203928aee4356845252ac6b662d5c72c29903813eJake Slack 22303928aee4356845252ac6b662d5c72c29903813eJake Slack 22403928aee4356845252ac6b662d5c72c29903813eJake Slack} 22503928aee4356845252ac6b662d5c72c29903813eJake Slack 22603928aee4356845252ac6b662d5c72c29903813eJake Slack 22703928aee4356845252ac6b662d5c72c29903813eJake Slack 228