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}