// ***************************************************************************************************************************
// * Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements.  See the NOTICE file *
// * distributed with this work for additional information regarding copyright ownership.  The ASF licenses this file        *
// * to you under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance            *
// * with the License.  You may obtain a copy of the License at                                                              *
// *                                                                                                                         *
// *  http://www.apache.org/licenses/LICENSE-2.0                                                                             *
// *                                                                                                                         *
// * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an  *
// * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the License for the        *
// * specific language governing permissions and limitations under the License.                                              *
// ***************************************************************************************************************************
package org.apache.juneau.http;

import org.apache.juneau.http.annotation.*;

/**
 * Represents a parsed <l>Range</l> HTTP request header.
 *
 * <p>
 * Request only part of an entity. Bytes are numbered from 0.
 *
 * <h5 class='figure'>Example</h5>
 * <p class='bcode w800'>
 * 	Range: bytes=500-999
 * </p>
 *
 * <h5 class='topic'>RFC2616 Specification</h5>
 *
 * Since all HTTP entities are represented in HTTP messages as sequences of bytes, the concept of a byte range is
 * meaningful for any HTTP entity.
 * (However, not all clients and servers need to support byte- range operations.)
 *
 * <p>
 * Byte range specifications in HTTP apply to the sequence of bytes in the entity-body (not necessarily the same as the
 * message-body).
 *
 * <p>
 * A byte range operation MAY specify a single range of bytes, or a set of ranges within a single entity.
 * <p class='bcode w800'>
 * 	ranges-specifier = byte-ranges-specifier
 * 	byte-ranges-specifier = bytes-unit "=" byte-range-set
 * 	byte-range-set  = 1#( byte-range-spec | suffix-byte-range-spec )
 * 	byte-range-spec = first-byte-pos "-" [last-byte-pos]
 * 	first-byte-pos  = 1*DIGIT
 * 	last-byte-pos   = 1*DIGIT
 * </p>
 *
 * <p>
 * The first-byte-pos value in a byte-range-spec gives the byte-offset of the first byte in a range.
 * The last-byte-pos value gives the byte-offset of the last byte in the range; that is, the byte positions specified
 * are inclusive.
 * Byte offsets start at zero.
 *
 * <p>
 * If the last-byte-pos value is present, it MUST be greater than or equal to the first-byte-pos in that
 * byte-range-spec, or the byte- range-spec is syntactically invalid.
 * The recipient of a byte-range- set that includes one or more syntactically invalid byte-range-spec values MUST
 * ignore the header field that includes that byte-range-set.
 *
 * <p>
 * If the last-byte-pos value is absent, or if the value is greater than or equal to the current length of the
 * entity-body, last-byte-pos is taken to be equal to one less than the current length of the entity-body in bytes.
 *
 * <p>
 * By its choice of last-byte-pos, a client can limit the number of bytes retrieved without knowing the size of the
 * entity.
 * <p class='bcode w800'>
 * 	suffix-byte-range-spec = "-" suffix-length
 * 	suffix-length = 1*DIGIT
 * </p>
 *
 * <p>
 * A suffix-byte-range-spec is used to specify the suffix of the entity-body, of a length given by the suffix-length
 * value.
 * (That is, this form specifies the last N bytes of an entity-body.)
 * If the entity is shorter than the specified suffix-length, the entire entity-body is used.
 *
 * <p>
 * If a syntactically valid byte-range-set includes at least one byte- range-spec whose first-byte-pos is less than the
 * current length of the entity-body, or at least one suffix-byte-range-spec with a non-zero suffix-length, then the
 * byte-range-set is satisfiable.
 * Otherwise, the byte-range-set is unsatisfiable.
 * If the byte-range-set is unsatisfiable, the server SHOULD return a response with a status of 416 (Requested range
 * not satisfiable).
 * Otherwise, the server SHOULD return a response with a status of 206 (Partial Content) containing the satisfiable
 * ranges of the entity-body.
 *
 * <p>
 * Examples of byte-ranges-specifier values (assuming an entity-body of length 10000):
 * <p class='bcode w800'>
 * 	- The first 500 bytes (byte offsets 0-499, inclusive):  bytes=0-499
 * 	- The second 500 bytes (byte offsets 500-999, inclusive):  bytes=500-999
 * 	- The final 500 bytes (byte offsets 9500-9999, inclusive):  bytes=-500
 * 	- Or bytes=9500-
 * 	- The first and last bytes only (bytes 0 and 9999):  bytes=0-0,-1
 * 	- Several legal but not canonical specifications of the second 500 bytes (byte offsets 500-999, inclusive):
 * 	   bytes=500-600,601-999
 * 	   bytes=500-700,601-999
 * </p>
 *
 * <p>
 * HTTP retrieval requests using conditional or unconditional GET methods MAY request one or more sub-ranges of the
 * entity, instead of the entire entity, using the Range request header, which applies to the entity returned as the
 * result of the request:
 *
 * <p class='bcode w800'>
 * 	Range = "Range" ":" ranges-specifier
 * </p>
 *
 * <p>
 * A server MAY ignore the Range header.
 * However, HTTP/1.1 origin servers and intermediate caches ought to support byte ranges when possible, since Range
 * supports efficient recovery from partially failed transfers, and supports efficient partial retrieval of large
 * entities.
 *
 * <p>
 * If the server supports the Range header and the specified range or ranges are appropriate for the entity:
 * <ul>
 * 	<li>The presence of a Range header in an unconditional GET modifies what is returned if the GET is otherwise
 * 		successful.
 * 		In other words, the response carries a status code of 206 (Partial Content) instead of 200 (OK).
 * 	<li>The presence of a Range header in a conditional GET (a request using one or both of If-Modified-Since and
 * 		If-None-Match, or one or both of If-Unmodified-Since and If-Match) modifies what is returned if the GET is
 * 		otherwise successful and the condition is true. It does not affect the 304 (Not Modified) response returned if
 * 		the conditional is false.
 * </ul>
 *
 * <p>
 * In some cases, it might be more appropriate to use the If-Range header (see section 14.27) in addition to the Range
 * header.
 *
 * <p>
 * If a proxy that supports ranges receives a Range request, forwards the request to an inbound server, and receives an
 * entire entity in reply, it SHOULD only return the requested range to its client.
 * It SHOULD store the entire received response in its cache if that is consistent with its cache allocation policies.
 *
 * <h5 class='section'>See Also:</h5>
 * <ul class='doctree'>
 * 	<li class='extlink'>{@doc RFC2616}
 * </ul>
 */
@Header("Range")
public final class Range extends HeaderString {

	/**
	 * Returns a parsed <code>Range</code> header.
	 *
	 * @param value The <code>Range</code> header string.
	 * @return The parsed <code>Range</code> header, or <jk>null</jk> if the string was null.
	 */
	public static Range forString(String value) {
		if (value == null)
			return null;
		return new Range(value);
	}

	private Range(String value) {
		super(value);
	}
}
