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