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