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.*;
018import org.apache.juneau.http.annotation.*;
019import org.apache.juneau.internal.*;
020
021/**
022 * Represents a parsed <l>TE</l> HTTP request header.
023 *
024 * <p>
025 * The transfer encodings the user agent is willing to accept: the same values as for the response header field
026 * Transfer-Encoding can be used, plus the "trailers" value (related to the "chunked" transfer method) to notify the
027 * server it expects to receive additional fields in the trailer after the last, zero-sized, chunk.
028 *
029 * <h5 class='figure'>Example</h5>
030 * <p class='bcode'>
031 *    TE: trailers, deflate
032 * </p>
033 *
034 * <h5 class='topic'>RFC2616 Specification</h5>
035 *
036 * The TE request-header field indicates what extension transfer-codings it is willing to accept in the response and
037 * whether or not it is willing to accept trailer fields in a chunked transfer-coding.
038 * Its value may consist of the keyword "trailers" and/or a comma-separated list of extension transfer-coding names
039 * with optional accept parameters (as described in section 3.6).
040 *
041 * <p class='bcode'>
042 *    TE        = "TE" ":" #( t-codings )
043 *    t-codings = "trailers" | ( transfer-extension [ accept-params ] )
044 * </p>
045 *
046 * <p>
047 * The presence of the keyword "trailers" indicates that the client is willing to accept trailer fields in a chunked
048 * transfer-coding, as defined in section 3.6.1.
049 * This keyword is reserved for use with transfer-coding values even though it does not itself represent a
050 * transfer-coding.
051 *
052 * <p>
053 * Examples of its use are:
054 * <p class='bcode'>
055 *    TE: deflate
056 *    TE:
057 *    TE: trailers, deflate;q=0.5
058 * </p>
059 *
060 * <p>
061 * The TE header field only applies to the immediate connection.
062 * Therefore, the keyword MUST be supplied within a Connection header field (section 14.10) whenever TE is present in
063 * an HTTP/1.1 message.
064 *
065 * <p>
066 * A server tests whether a transfer-coding is acceptable, according to a TE field, using these rules:
067 * <ol>
068 *    <li>The "chunked" transfer-coding is always acceptable.
069 *       If the keyword "trailers" is listed, the client indicates that it is willing to accept trailer fields in the
070 *       chunked response on behalf of itself and any downstream clients.
071 *       The implication is that, if given, the client is stating that either all downstream clients are willing to accept
072 *       trailer fields in the forwarded response, or that it will attempt to buffer the response on behalf of downstream
073 *       recipients.
074 *       Note: HTTP/1.1 does not define any means to limit the size of a chunked response such that a client can be assured
075 *       of buffering the entire response.
076 *    <li>If the transfer-coding being tested is one of the transfer-codings listed in the TE field, then it is acceptable
077 *       unless it is accompanied by a qvalue of 0. (As defined in section 3.9, a qvalue of 0 means "not acceptable.")
078 *    <li>If multiple transfer-codings are acceptable, then the acceptable transfer-coding with the highest non-zero
079 *       qvalue is preferred.
080 *       The "chunked" transfer-coding always has a qvalue of 1.
081 * </ol>
082 *
083 * <p>
084 * If the TE field-value is empty or if no TE field is present, the only transfer-coding is "chunked".
085 * A message with no transfer-coding is always acceptable.
086 *
087 * <h5 class='section'>See Also:</h5><ul>
088 *    <li class='link'><a class="doclink" href="../../../../../index.html#juneau-rest-common">juneau-rest-common</a>
089 *    <li class='extlink'><a class="doclink" href="https://www.w3.org/Protocols/rfc2616/rfc2616.html">Hypertext Transfer Protocol -- HTTP/1.1</a>
090 * </ul>
091 *
092 * @serial exclude
093 */
094@Header("TE")
095public class TE extends BasicStringRangesHeader {
096
097   //-----------------------------------------------------------------------------------------------------------------
098   // Static
099   //-----------------------------------------------------------------------------------------------------------------
100
101   private static final long serialVersionUID = 1L;
102   private static final String NAME = "TE";
103
104   private static final Cache<String,TE> CACHE = Cache.of(String.class, TE.class).build();
105
106   /**
107    * Static creator.
108    *
109    * @param value
110    *    The header value.
111    *    <br>Must be parsable by {@link StringRanges#of(String)}.
112    *    <br>Can be <jk>null</jk>.
113    * @return A new header bean, or <jk>null</jk> if the value is <jk>null</jk>.
114    */
115   public static TE of(String value) {
116      return value == null ? null : CACHE.get(value, ()->new TE(value));
117   }
118
119   /**
120    * Static creator.
121    *
122    * @param value
123    *    The header value.
124    *    <br>Can be <jk>null</jk>.
125    * @return A new header bean, or <jk>null</jk> if the value is <jk>null</jk>.
126    */
127   public static TE of(StringRanges value) {
128      return value == null ? null : new TE(value);
129   }
130
131   /**
132    * Static creator with delayed value.
133    *
134    * <p>
135    * Header value is re-evaluated on each call to {@link #getValue()}.
136    *
137    * @param value
138    *    The supplier of the header value.
139    *    <br>Can be <jk>null</jk>.
140    * @return A new header bean, or <jk>null</jk> if the value is <jk>null</jk>.
141    */
142   public static TE of(Supplier<StringRanges> value) {
143      return value == null ? null : new TE(value);
144   }
145
146   //-----------------------------------------------------------------------------------------------------------------
147   // Instance
148   //-----------------------------------------------------------------------------------------------------------------
149
150   /**
151    * Constructor.
152    *
153    * @param value
154    *    The header value.
155    *    <br>Must be parsable by {@link StringRanges#of(String)}.
156    *    <br>Can be <jk>null</jk>.
157    */
158   public TE(String value) {
159      super(NAME, value);
160   }
161
162   /**
163    * Constructor.
164    *
165    * @param value
166    *    The header value.
167    *    <br>Can be <jk>null</jk>.
168    */
169   public TE(StringRanges value) {
170      super(NAME, value);
171   }
172
173   /**
174    * Constructor 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    */
183   public TE(Supplier<StringRanges> value) {
184      super(NAME, value);
185   }
186}