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'> 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'> 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'> 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'> 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'> 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 * <h5 class='section'>See Also:</h5><ul> 141 * <li class='link'><a class="doclink" href="../../../../../index.html#juneau-rest-common">juneau-rest-common</a> 142 * <li class='extlink'><a class="doclink" href="https://www.w3.org/Protocols/rfc2616/rfc2616.html">Hypertext Transfer Protocol -- HTTP/1.1</a> 143 * </ul> 144 * 145 * @serial exclude 146 */ 147@Header("Range") 148public class Range extends BasicStringHeader { 149 150 //----------------------------------------------------------------------------------------------------------------- 151 // Static 152 //----------------------------------------------------------------------------------------------------------------- 153 154 private static final long serialVersionUID = 1L; 155 private static final String NAME = "Range"; 156 157 /** 158 * Static creator. 159 * 160 * @param value 161 * The header value. 162 * <br>Can be <jk>null</jk>. 163 * @return A new header bean, or <jk>null</jk> if the value is <jk>null</jk>. 164 */ 165 public static Range of(String value) { 166 return value == null ? null : new Range(value); 167 } 168 169 /** 170 * Static creator with delayed value. 171 * 172 * <p> 173 * Header value is re-evaluated on each call to {@link #getValue()}. 174 * 175 * @param value 176 * The supplier of the header value. 177 * <br>Can be <jk>null</jk>. 178 * @return A new header bean, or <jk>null</jk> if the value is <jk>null</jk>. 179 */ 180 public static Range of(Supplier<String> value) { 181 return value == null ? null : new Range(value); 182 } 183 184 //----------------------------------------------------------------------------------------------------------------- 185 // Instance 186 //----------------------------------------------------------------------------------------------------------------- 187 188 /** 189 * Constructor. 190 * 191 * @param value 192 * The header value. 193 * <br>Can be <jk>null</jk>. 194 */ 195 public Range(String value) { 196 super(NAME, value); 197 } 198 199 /** 200 * Constructor with delayed value. 201 * 202 * <p> 203 * Header value is re-evaluated on each call to {@link #getValue()}. 204 * 205 * @param value 206 * The supplier of the header value. 207 * <br>Can be <jk>null</jk>. 208 */ 209 public Range(Supplier<String> value) { 210 super(NAME, value); 211 } 212}