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