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.*;
016import java.util.function.*;
017
018import org.apache.juneau.http.annotation.*;
019
020/**
021 * Represents a parsed <l>Via</l> HTTP response header.
022 *
023 * <p>
024 * Informs the client of proxies through which the response was sent.
025 *
026 * <h5 class='figure'>Example</h5>
027 * <p class='bcode w800'>
028 *    Via: 1.0 fred, 1.1 example.com (Apache/1.1)
029 * </p>
030 *
031 * <p>
032 * Informs the client of proxies through which the response was sent.
033 *
034 * <p>
035 * <h5 class='figure'>Example</h5>
036 * <p class='bcode w800'>
037 *    Via: 1.0 fred, 1.1 example.com (Apache/1.1)
038 * </p>
039 *
040 * <p>
041 * <h5 class='topic'>RFC2616 Specification</h5>
042 *
043 * The Via general-header field MUST be used by gateways and proxies to indicate the intermediate protocols and
044 * recipients between the user agent and the server on requests, and between the origin server and the client on
045 * responses.
046 * It is analogous to the "Received" field of RFC 822 and is intended to be used for tracking message forwards,
047 * avoiding request loops, and identifying the protocol capabilities of all senders along the request/response chain.
048 *
049 * <p class='bcode w800'>
050 *    Via =  "Via" ":" 1#( received-protocol received-by [ comment ] )
051 *    received-protocol = [ protocol-name "/" ] protocol-version
052 *    protocol-name     = token
053 *    protocol-version  = token
054 *    received-by       = ( host [ ":" port ] ) | pseudonym
055 *    pseudonym         = token
056 * </p>
057 *
058 * <p>
059 * The received-protocol indicates the protocol version of the message received by the server or client along each
060 * segment of the request/response chain.
061 * The received-protocol version is appended to the Via field value when the message is forwarded so that information
062 * about the protocol capabilities of upstream applications remains visible to all recipients.
063 *
064 * <p>
065 * The protocol-name is optional if and only if it would be "HTTP".
066 * The received-by field is normally the host and optional port number of a recipient server or client that subsequently
067 * forwarded the message.
068 * However, if the real host is considered to be sensitive information, it MAY be replaced by a pseudonym.
069 * If the port is not given, it MAY be assumed to be the default port of the received-protocol.
070 *
071 * <p>
072 * Multiple Via field values represents each proxy or gateway that has forwarded the message.
073 * Each recipient MUST append its information such that the end result is ordered according to the sequence of
074 * forwarding applications.
075 *
076 * <p>
077 * Comments MAY be used in the Via header field to identify the software of the recipient proxy or gateway, analogous
078 * to the User-Agent and Server header fields.
079 * However, all comments in the Via field are optional and MAY be removed by any recipient prior to forwarding the
080 * message.
081 *
082 * <p>
083 * For example, a request message could be sent from an HTTP/1.0 user agent to an internal proxy code-named "fred",
084 * which uses HTTP/1.1 to forward the request to a public proxy at nowhere.com, which completes the request by
085 * forwarding it to the origin server at www.ics.uci.edu.
086 * The request received by www.ics.uci.edu would then have the following Via header field:
087 * <p class='bcode w800'>
088 *    Via: 1.0 fred, 1.1 nowhere.com (Apache/1.1)
089 * </p>
090 *
091 * <p>
092 * Proxies and gateways used as a portal through a network firewall SHOULD NOT, by default, forward the names and ports
093 * of hosts within the firewall region.
094 * This information SHOULD only be propagated if explicitly enabled.
095 * If not enabled, the received-by host of any host behind the firewall SHOULD be replaced by an appropriate pseudonym
096 * for that host.
097 *
098 * <p>
099 * For organizations that have strong privacy requirements for hiding internal structures, a proxy MAY combine an
100 * ordered subsequence of Via header field entries with identical received-protocol values into a single such entry.
101 * For example...
102 * <p class='bcode w800'>
103 *    Via: 1.0 ricky, 1.1 ethel, 1.1 fred, 1.0 lucy
104 * </p>
105 *
106 * <p>
107 * ...could be collapsed to...
108 * <p class='bcode w800'>
109 *    Via: 1.0 ricky, 1.1 mertz, 1.0 lucy
110 * </p>
111 *
112 * <p>
113 * Applications SHOULD NOT combine multiple entries unless they are all under the same organizational control and the
114 * hosts have already been replaced by pseudonyms.
115 * Applications MUST NOT combine entries which have different received-protocol values.
116 *
117 * <ul class='seealso'>
118 *    <li class='extlink'>{@doc ExtRFC2616}
119 * </ul>
120 */
121@Header("Via")
122public class Via extends BasicCsvArrayHeader {
123
124   private static final long serialVersionUID = 1L;
125
126   /**
127    * Convenience creator.
128    *
129    * @param value
130    *    The header value supplier.
131    *    <br>Can be any of the following:
132    *    <ul>
133    *       <li><c>String</c> - A comma-delimited string.
134    *       <li><c>String[]</c> - A pre-parsed value.
135    *       <li>Any other array type - Converted to <c>String[]</c>.
136    *       <li>Any {@link Collection} - Converted to <c>String[]</c>.
137    *       <li>Anything else - Converted to <c>String</c>.
138    *    </ul>
139    * @return The parsed <c>Via</c> header, or <jk>null</jk> if the value was null.
140    */
141   public static Via of(Object value) {
142      if (value == null)
143         return null;
144      return new Via(value);
145   }
146
147   /**
148    * Convenience creator using supplier.
149    *
150    * <p>
151    * Header value is re-evaluated on each call to {@link #getValue()}.
152    *
153    * @param value
154    *    The header value supplier.
155    *    <br>Can be any of the following:
156    *    <ul>
157    *       <li><c>String</c> - A comma-delimited string.
158    *       <li><c>String[]</c> - A pre-parsed value.
159    *       <li>Any other array type - Converted to <c>String[]</c>.
160    *       <li>Any {@link Collection} - Converted to <c>String[]</c>.
161    *       <li>Anything else - Converted to <c>String</c>.
162    *    </ul>
163    * @return The parsed <c>Via</c> header, or <jk>null</jk> if the value was null.
164    */
165   public static Via of(Supplier<?> value) {
166      if (value == null)
167         return null;
168      return new Via(value);
169   }
170
171   /**
172    * Constructor.
173    *
174    * @param value
175    *    The header value.
176    *    <br>Can be any of the following:
177    *    <ul>
178    *       <li><c>String</c> - A comma-delimited string.
179    *       <li><c>String[]</c> - A pre-parsed value.
180    *       <li>Any other array type - Converted to <c>String[]</c>.
181    *       <li>Any {@link Collection} - Converted to <c>String[]</c>.
182    *       <li>Anything else - Converted to <c>String</c>.
183    *       <li>A {@link Supplier} of anything on this list.
184    *    </ul>
185    */
186   public Via(Object value) {
187      super("Via", value);
188   }
189
190   /**
191    * Constructor
192    *
193    * @param value
194    *    The header value.
195    */
196   public Via(String value) {
197      this((Object)value);
198   }
199}