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;
014
015import static org.apache.juneau.http.Constants.*;
016
017import org.apache.juneau.internal.*;
018
019/**
020 * Represents a parsed <l>TE</l> HTTP request header.
021 * 
022 * <p>
023 * The transfer encodings the user agent is willing to accept: the same values as for the response header field
024 * Transfer-Encoding can be used, plus the "trailers" value (related to the "chunked" transfer method) to notify the
025 * server it expects to receive additional fields in the trailer after the last, zero-sized, chunk.
026 * 
027 * <h5 class='figure'>Example</h5>
028 * <p class='bcode'>
029 *    TE: trailers, deflate
030 * </p>
031 * 
032 * <h5 class='topic'>RFC2616 Specification</h5>
033 * 
034 * The TE request-header field indicates what extension transfer-codings it is willing to accept in the response and
035 * whether or not it is willing to accept trailer fields in a chunked transfer-coding.
036 * Its value may consist of the keyword "trailers" and/or a comma-separated list of extension transfer-coding names
037 * with optional accept parameters (as described in section 3.6).
038 * 
039 * <p class='bcode'>
040 *    TE        = "TE" ":" #( t-codings )
041 *    t-codings = "trailers" | ( transfer-extension [ accept-params ] )
042 * </p>
043 * 
044 * <p>
045 * The presence of the keyword "trailers" indicates that the client is willing to accept trailer fields in a chunked
046 * transfer-coding, as defined in section 3.6.1.
047 * This keyword is reserved for use with transfer-coding values even though it does not itself represent a
048 * transfer-coding.
049 * 
050 * <p>
051 * Examples of its use are:
052 * <p class='bcode'>
053 *    TE: deflate
054 *    TE:
055 *    TE: trailers, deflate;q=0.5
056 * </p>
057 * 
058 * <p>
059 * The TE header field only applies to the immediate connection.
060 * Therefore, the keyword MUST be supplied within a Connection header field (section 14.10) whenever TE is present in
061 * an HTTP/1.1 message.
062 * 
063 * <p>
064 * A server tests whether a transfer-coding is acceptable, according to a TE field, using these rules:
065 * <ol>
066 *    <li>The "chunked" transfer-coding is always acceptable.
067 *       If the keyword "trailers" is listed, the client indicates that it is willing to accept trailer fields in the
068 *       chunked response on behalf of itself and any downstream clients.
069 *       The implication is that, if given, the client is stating that either all downstream clients are willing to accept
070 *       trailer fields in the forwarded response, or that it will attempt to buffer the response on behalf of downstream
071 *       recipients.
072 *       Note: HTTP/1.1 does not define any means to limit the size of a chunked response such that a client can be assured
073 *       of buffering the entire response.
074 *    <li>If the transfer-coding being tested is one of the transfer-codings listed in the TE field, then it is acceptable
075 *       unless it is accompanied by a qvalue of 0. (As defined in section 3.9, a qvalue of 0 means "not acceptable.")
076 *    <li>If multiple transfer-codings are acceptable, then the acceptable transfer-coding with the highest non-zero
077 *       qvalue is preferred.
078 *       The "chunked" transfer-coding always has a qvalue of 1.
079 * </ol>
080 * 
081 * <p>
082 * If the TE field-value is empty or if no TE field is present, the only transfer-coding is "chunked".
083 * A message with no transfer-coding is always acceptable.
084 * 
085 * <h5 class='section'>See Also:</h5>
086 * <ul class='doctree'>
087 *    <li class='extlink'><a class='doclink' href='https://www.w3.org/Protocols/rfc2616/rfc2616.html'>Hypertext Transfer Protocol -- HTTP/1.1</a>
088 * </ul>
089 */
090public final class TE extends HeaderRangeArray {
091
092   private static final Cache<String,TE> cache = new Cache<>(NOCACHE, CACHE_MAX_SIZE);
093
094   /**
095    * Returns a parsed <code>Accept</code> header.
096    * 
097    * @param value The <code>Accept</code> header string.
098    * @return The parsed <code>Accept</code> header, or <jk>null</jk> if the string was null.
099    */
100   public static TE forString(String value) {
101      if (value == null)
102         return null;
103      TE te = cache.get(value);
104      if (te == null)
105         te = cache.put(value, new TE(value));
106      return te;
107   }
108
109   private TE(String value) {
110      super(value);
111   }
112}