001// ***************************************************************************************************************************
002// * Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements.  See the NOTICE file *
003// * distributed with this work for additional information regarding copyright ownership.  The ASF licenses this file        *
004// * to you under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance            *
005// * with the License.  You may obtain a copy of the License at                                                              *
006// *                                                                                                                         *
007// *  http://www.apache.org/licenses/LICENSE-2.0                                                                             *
008// *                                                                                                                         *
009// * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an  *
010// * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the License for the        *
011// * specific language governing permissions and limitations under the License.                                              *
012// ***************************************************************************************************************************
013package org.apache.juneau.http.header;
014
015import java.util.function.*;
016
017import org.apache.juneau.http.annotation.*;
018
019/**
020 * Represents a parsed <l>Range</l> HTTP request header.
021 *
022 * <p>
023 * Request only part of an entity. Bytes are numbered from 0.
024 *
025 * <h5 class='figure'>Example</h5>
026 * <p class='bcode w800'>
027 *    Range: bytes=500-999
028 * </p>
029 *
030 * <h5 class='topic'>RFC2616 Specification</h5>
031 *
032 * Since all HTTP entities are represented in HTTP messages as sequences of bytes, the concept of a byte range is
033 * meaningful for any HTTP entity.
034 * (However, not all clients and servers need to support byte- range operations.)
035 *
036 * <p>
037 * Byte range specifications in HTTP apply to the sequence of bytes in the entity-body (not necessarily the same as the
038 * message-body).
039 *
040 * <p>
041 * A byte range operation MAY specify a single range of bytes, or a set of ranges within a single entity.
042 * <p class='bcode w800'>
043 *    ranges-specifier = byte-ranges-specifier
044 *    byte-ranges-specifier = bytes-unit "=" byte-range-set
045 *    byte-range-set  = 1#( byte-range-spec | suffix-byte-range-spec )
046 *    byte-range-spec = first-byte-pos "-" [last-byte-pos]
047 *    first-byte-pos  = 1*DIGIT
048 *    last-byte-pos   = 1*DIGIT
049 * </p>
050 *
051 * <p>
052 * The first-byte-pos value in a byte-range-spec gives the byte-offset of the first byte in a range.
053 * The last-byte-pos value gives the byte-offset of the last byte in the range; that is, the byte positions specified
054 * are inclusive.
055 * Byte offsets start at zero.
056 *
057 * <p>
058 * If the last-byte-pos value is present, it MUST be greater than or equal to the first-byte-pos in that
059 * byte-range-spec, or the byte- range-spec is syntactically invalid.
060 * The recipient of a byte-range- set that includes one or more syntactically invalid byte-range-spec values MUST
061 * ignore the header field that includes that byte-range-set.
062 *
063 * <p>
064 * If the last-byte-pos value is absent, or if the value is greater than or equal to the current length of the
065 * entity-body, last-byte-pos is taken to be equal to one less than the current length of the entity-body in bytes.
066 *
067 * <p>
068 * By its choice of last-byte-pos, a client can limit the number of bytes retrieved without knowing the size of the
069 * entity.
070 * <p class='bcode w800'>
071 *    suffix-byte-range-spec = "-" suffix-length
072 *    suffix-length = 1*DIGIT
073 * </p>
074 *
075 * <p>
076 * A suffix-byte-range-spec is used to specify the suffix of the entity-body, of a length given by the suffix-length
077 * value.
078 * (That is, this form specifies the last N bytes of an entity-body.)
079 * If the entity is shorter than the specified suffix-length, the entire entity-body is used.
080 *
081 * <p>
082 * If a syntactically valid byte-range-set includes at least one byte- range-spec whose first-byte-pos is less than the
083 * current length of the entity-body, or at least one suffix-byte-range-spec with a non-zero suffix-length, then the
084 * byte-range-set is satisfiable.
085 * Otherwise, the byte-range-set is unsatisfiable.
086 * If the byte-range-set is unsatisfiable, the server SHOULD return a response with a status of 416 (Requested range
087 * not satisfiable).
088 * Otherwise, the server SHOULD return a response with a status of 206 (Partial Content) containing the satisfiable
089 * ranges of the entity-body.
090 *
091 * <p>
092 * Examples of byte-ranges-specifier values (assuming an entity-body of length 10000):
093 * <p class='bcode w800'>
094 *    - The first 500 bytes (byte offsets 0-499, inclusive):  bytes=0-499
095 *    - The second 500 bytes (byte offsets 500-999, inclusive):  bytes=500-999
096 *    - The final 500 bytes (byte offsets 9500-9999, inclusive):  bytes=-500
097 *    - Or bytes=9500-
098 *    - The first and last bytes only (bytes 0 and 9999):  bytes=0-0,-1
099 *    - Several legal but not canonical specifications of the second 500 bytes (byte offsets 500-999, inclusive):
100 *       bytes=500-600,601-999
101 *       bytes=500-700,601-999
102 * </p>
103 *
104 * <p>
105 * HTTP retrieval requests using conditional or unconditional GET methods MAY request one or more sub-ranges of the
106 * entity, instead of the entire entity, using the Range request header, which applies to the entity returned as the
107 * result of the request:
108 *
109 * <p class='bcode w800'>
110 *    Range = "Range" ":" ranges-specifier
111 * </p>
112 *
113 * <p>
114 * A server MAY ignore the Range header.
115 * However, HTTP/1.1 origin servers and intermediate caches ought to support byte ranges when possible, since Range
116 * supports efficient recovery from partially failed transfers, and supports efficient partial retrieval of large
117 * entities.
118 *
119 * <p>
120 * If the server supports the Range header and the specified range or ranges are appropriate for the entity:
121 * <ul>
122 *    <li>The presence of a Range header in an unconditional GET modifies what is returned if the GET is otherwise
123 *       successful.
124 *       In other words, the response carries a status code of 206 (Partial Content) instead of 200 (OK).
125 *    <li>The presence of a Range header in a conditional GET (a request using one or both of If-Modified-Since and
126 *       If-None-Match, or one or both of If-Unmodified-Since and If-Match) modifies what is returned if the GET is
127 *       otherwise successful and the condition is true. It does not affect the 304 (Not Modified) response returned if
128 *       the conditional is false.
129 * </ul>
130 *
131 * <p>
132 * In some cases, it might be more appropriate to use the If-Range header (see section 14.27) in addition to the Range
133 * header.
134 *
135 * <p>
136 * If a proxy that supports ranges receives a Range request, forwards the request to an inbound server, and receives an
137 * entire entity in reply, it SHOULD only return the requested range to its client.
138 * It SHOULD store the entire received response in its cache if that is consistent with its cache allocation policies.
139 *
140 * <ul class='seealso'>
141 *    <li class='extlink'>{@doc ExtRFC2616}
142 * </ul>
143 */
144@Header("Range")
145public class Range extends BasicStringHeader {
146
147   private static final long serialVersionUID = 1L;
148
149   /**
150    * Convenience creator.
151    *
152    * @param value
153    *    The header value.
154    *    <br>Can be any of the following:
155    *    <ul>
156    *       <li>{@link String}
157    *       <li>Anything else - Converted to <c>String</c> then parsed.
158    *    </ul>
159    * @return A new {@link Range} object.
160    */
161   public static Range of(Object value) {
162      if (value == null)
163         return null;
164      return new Range(value);
165   }
166
167   /**
168    * Convenience creator using supplier.
169    *
170    * <p>
171    * Header value is re-evaluated on each call to {@link #getValue()}.
172    *
173    * @param value
174    *    The header value supplier.
175    *    <br>Can be any of the following:
176    *    <ul>
177    *       <li>{@link String}
178    *       <li>Anything else - Converted to <c>String</c> then parsed.
179    *    </ul>
180    * @return A new {@link Range} object.
181    */
182   public static Range of(Supplier<?> value) {
183      if (value == null)
184         return null;
185      return new Range(value);
186   }
187
188   /**
189    * Constructor.
190    *
191    * @param value
192    *    The header value.
193    *    <br>Can be any of the following:
194    *    <ul>
195    *       <li>{@link String}
196    *       <li>Anything else - Converted to <c>String</c> then parsed.
197    *       <li>A {@link Supplier} of anything on this list.
198    *    </ul>
199    */
200   public Range(Object value) {
201      super("Range", value);
202   }
203
204   /**
205    * Constructor
206    *
207    * @param value
208    *    The header value.
209    */
210   public Range(String value) {
211      this((Object)value);
212   }
213}