You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@juneau.apache.org by ja...@apache.org on 2017/05/06 16:24:36 UTC

[1/4] incubator-juneau git commit: Add HTTP header classes.

Repository: incubator-juneau
Updated Branches:
  refs/heads/master de98f18d6 -> fa4736b6d


http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/fa4736b6/juneau-core/src/main/java/org/apache/juneau/http/TypeRange.java
----------------------------------------------------------------------
diff --git a/juneau-core/src/main/java/org/apache/juneau/http/TypeRange.java b/juneau-core/src/main/java/org/apache/juneau/http/TypeRange.java
deleted file mode 100644
index a05189f..0000000
--- a/juneau-core/src/main/java/org/apache/juneau/http/TypeRange.java
+++ /dev/null
@@ -1,276 +0,0 @@
-// ***************************************************************************************************************************
-// * Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements.  See the NOTICE file *
-// * distributed with this work for additional information regarding copyright ownership.  The ASF licenses this file        *
-// * to you under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance            *
-// * with the License.  You may obtain a copy of the License at                                                              *
-// *                                                                                                                         *
-// *  http://www.apache.org/licenses/LICENSE-2.0                                                                             *
-// *                                                                                                                         *
-// * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an  *
-// * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the License for the        *
-// * specific language governing permissions and limitations under the License.                                              *
-// ***************************************************************************************************************************
-package org.apache.juneau.http;
-
-import java.util.*;
-import java.util.Map.*;
-
-import org.apache.juneau.annotation.*;
-import org.apache.juneau.internal.*;
-
-/**
- * Represents a single value in a comma-delimited header value that optionally contains a quality
- * metric for comparison and extension parameters.
- * <p>
- * Similar in concept to {@link MediaTypeRange} except instead of media types (e.g. <js>"text/json"</js>),
- * it's a simple type (e.g. <js>"iso-8601"</js>).
- * <p>
- * An example of a type range is a value in an <code>Accept-Encoding</code> header.
- */
-@BeanIgnore
-public final class TypeRange implements Comparable<TypeRange>  {
-
-	private static final TypeRange[] DEFAULT = new TypeRange[]{new TypeRange("*")};
-
-	private final String type;
-	private final Float qValue;
-	private final Map<String,Set<String>> extensions;
-
-	/**
-	 * Parses a header such as an <code>Accept-Encoding</code> header value into an array of type ranges.
-	 * <p>
-	 * The syntax expected to be found in the referenced <code>value</code> complies with the syntax described in RFC2616, Section 14.1, as described below:
-	 * <p class='bcode'>
-	 * 	Accept-Encoding  = "Accept-Encoding" ":"
-	 * 	                   1#( codings [ ";" "q" "=" qvalue ] )
-	 * 	codings          = ( content-coding | "*" )
-	 * </p>
-	 * <p>
-	 * Examples of its use are:
-	 * <p class='bcode'>
-	 * 	Accept-Encoding: compress, gzip
-	 * 	Accept-Encoding:
-	 * 	Accept-Encoding: *
-	 * 	Accept-Encoding: compress;q=0.5, gzip;q=1.0
-	 * 	Accept-Encoding: gzip;q=1.0, identity; q=0.5, *;q=0
-	 * </p>
-	 *
-	 * @param value The value to parse.  If <jk>null</jk> or empty, returns a single <code>TypeRange</code> is returned that represents all types.
-	 * @return The type ranges described by the string.
-	 * <br>The ranges are sorted such that the most acceptable type is available at ordinal position <js>'0'</js>, and the least acceptable at position n-1.
-	 */
-	public static TypeRange[] parse(String value) {
-
-		if (value == null || value.length() == 0)
-			return DEFAULT;
-
-		if (value.indexOf(',') == -1)
-			return new TypeRange[]{new TypeRange(value)};
-
-		Set<TypeRange> ranges = new TreeSet<TypeRange>();
-
-		for (String r : StringUtils.split(value, ',')) {
-			r = r.trim();
-
-			if (r.isEmpty())
-				continue;
-
-			ranges.add(new TypeRange(r));
-		}
-
-		return ranges.toArray(new TypeRange[ranges.size()]);
-	}
-
-	@SuppressWarnings("unchecked")
-	private TypeRange(String token) {
-		Builder b = new Builder(token);
-		this.type = b.type;
-		this.qValue = b.qValue;
-		this.extensions = (b.extensions == null ? Collections.EMPTY_MAP : Collections.unmodifiableMap(b.extensions));
-	}
-
-	private static class Builder {
-		private String type;
-		private Float qValue = 1f;
-		private Map<String,Set<String>> extensions;
-
-		private Builder(String token) {
-
-			token = token.trim();
-
-			int i = token.indexOf(";q=");
-
-			if (i == -1) {
-				type = token;
-				return;
-			}
-
-			type = token.substring(0, i);
-
-			String[] tokens = token.substring(i+1).split(";");
-
-			// Only the type of the range is specified
-			if (tokens.length > 0) {
-				boolean isInExtensions = false;
-				for (int j = 0; j < tokens.length; j++) {
-					String[] parm = tokens[j].split("=");
-					if (parm.length == 2) {
-						String k = parm[0], v = parm[1];
-						if (isInExtensions) {
-							if (extensions == null)
-								extensions = new TreeMap<String,Set<String>>();
-							if (! extensions.containsKey(k))
-								extensions.put(k, new TreeSet<String>());
-							extensions.get(k).add(v);
-						} else if (k.equals("q")) {
-							qValue = new Float(v);
-							isInExtensions = true;
-						}
-					}
-				}
-			}
-		}
-	}
-
-	/**
-	 * Returns the type enclosed by this type range.
-	 *
-	 * <h5 class='section'>Examples:</h5>
-	 * <ul>
-	 * 	<li><js>"compress"</js>
-	 * 	<li><js>"gzip"</js>
-	 * 	<li><js>"*"</js>
-	 * </ul>
-	 *
-	 * @return The type of this type range, lowercased, never <jk>null</jk>.
-	 */
-	public String getType() {
-		return type;
-	}
-
-	/**
-	 * Returns the <js>'q'</js> (quality) value for this type, as described in Section 3.9 of RFC2616.
-	 * <p>
-	 * The quality value is a float between <code>0.0</code> (unacceptable) and <code>1.0</code> (most acceptable).
-	 * <p>
-	 * If 'q' value doesn't make sense for the context (e.g. this range was extracted from a <js>"content-*"</js> header, as opposed to <js>"accept-*"</js>
-	 * header, its value will always be <js>"1"</js>.
-	 *
-	 * @return The 'q' value for this type, never <jk>null</jk>.
-	 */
-	public Float getQValue() {
-		return qValue;
-	}
-
-	/**
-	 * Returns the optional set of custom extensions defined for this type.
-	 * <p>
-	 * Values are lowercase and never <jk>null</jk>.
-	 *
-	 * @return The optional list of extensions, never <jk>null</jk>.
-	 */
-	public Map<String,Set<String>> getExtensions() {
-		return extensions;
-	}
-
-	/**
-	 * Provides a string representation of this media range, suitable for use as an <code>Accept</code> header value.
-	 * <p>
-	 * The literal text generated will be all lowercase.
-	 *
-	 * @return A media range suitable for use as an Accept header value, never <code>null</code>.
-	 */
-	@Override /* Object */
-	public String toString() {
-		StringBuffer sb = new StringBuffer().append(type);
-
-		// '1' is equivalent to specifying no qValue. If there's no extensions, then we won't include a qValue.
-		if (qValue.floatValue() == 1.0) {
-			if (! extensions.isEmpty()) {
-				sb.append(";q=").append(qValue);
-				for (Entry<String,Set<String>> e : extensions.entrySet()) {
-					String k = e.getKey();
-					for (String v : e.getValue())
-						sb.append(';').append(k).append('=').append(v);
-				}
-			}
-		} else {
-			sb.append(";q=").append(qValue);
-			for (Entry<String,Set<String>> e : extensions.entrySet()) {
-				String k = e.getKey();
-				for (String v : e.getValue())
-					sb.append(';').append(k).append('=').append(v);
-			}
-		}
-		return sb.toString();
-	}
-
-	/**
-	 * Returns <jk>true</jk> if the specified object is also a <code>MediaType</code>, and has the same qValue, type, parameters, and extensions.
-	 *
-	 * @return <jk>true</jk> if object is equivalent.
-	 */
-	@Override /* Object */
-	public boolean equals(Object o) {
-
-		if (o == null || !(o instanceof TypeRange))
-			return false;
-
-		if (this == o)
-			return true;
-
-		TypeRange o2 = (TypeRange) o;
-		return qValue.equals(o2.qValue)
-			&& type.equals(o2.type)
-			&& extensions.equals(o2.extensions);
-	}
-
-	/**
-	 * Returns a hash based on this instance's <code>media-type</code>.
-	 *
-	 * @return A hash based on this instance's <code>media-type</code>.
-	 */
-	@Override /* Object */
-	public int hashCode() {
-		return type.hashCode();
-	}
-
-	/**
-	 * Compares two MediaRanges for equality.
-	 * <p>
-	 * The values are first compared according to <code>qValue</code> values.
-	 * Should those values be equal, the <code>type</code> is then lexicographically compared (case-insensitive) in ascending order,
-	 * 	with the <js>"*"</js> type demoted last in that order.
-	 * <code>TypeRanges</code> with the same types but with extensions are promoted over those same types with no extensions.
-	 *
-	 * @param o The range to compare to.  Never <jk>null</jk>.
-	 */
-	@Override /* Comparable */
-	public int compareTo(TypeRange o) {
-
-		// Compare q-values.
-		int qCompare = Float.compare(o.qValue, qValue);
-		if (qCompare != 0)
-			return qCompare;
-
-		// Compare media-types.
-		// Note that '*' comes alphabetically before letters, so just do a reverse-alphabetical comparison.
-		int i = o.type.toString().compareTo(type.toString());
-		return i;
-	}
-
-	/**
-	 * Checks if the specified type matches this range.
-	 * <p>
-	 * The type will match this range if the range type string is the same or <js>"*"</js>.
-	 *
-	 * @param type The type to match against this range.
-	 * @return <jk>true</jk> if the specified type matches this range.
-	 */
-	@SuppressWarnings("hiding")
-	public boolean matches(String type) {
-		if (qValue == 0)
-			return false;
-		return this.type.equals(type) || this.type.equals("*");
-	}
-}

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/fa4736b6/juneau-core/src/main/java/org/apache/juneau/http/Upgrade.java
----------------------------------------------------------------------
diff --git a/juneau-core/src/main/java/org/apache/juneau/http/Upgrade.java b/juneau-core/src/main/java/org/apache/juneau/http/Upgrade.java
new file mode 100644
index 0000000..344943c
--- /dev/null
+++ b/juneau-core/src/main/java/org/apache/juneau/http/Upgrade.java
@@ -0,0 +1,84 @@
+// ***************************************************************************************************************************
+// * Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements.  See the NOTICE file *
+// * distributed with this work for additional information regarding copyright ownership.  The ASF licenses this file        *
+// * to you under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance            *
+// * with the License.  You may obtain a copy of the License at                                                              *
+// *                                                                                                                         *
+// *  http://www.apache.org/licenses/LICENSE-2.0                                                                             *
+// *                                                                                                                         *
+// * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an  *
+// * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the License for the        *
+// * specific language governing permissions and limitations under the License.                                              *
+// ***************************************************************************************************************************
+package org.apache.juneau.http;
+
+/**
+ * Represents a parsed <l>Upgrade</l> HTTP request header.
+ * <p>
+ * Ask the client to upgrade to another protocol.
+ *
+ * <h6 class='figure'>Example</h6>
+ * <p class='bcode'>
+ * 	Upgrade: HTTP/2.0, HTTPS/1.3, IRC/6.9, RTA/x11, websocket
+ * </p>
+ *
+ * <h6 class='topic'>RFC2616 Specification</h6>
+ * The Upgrade general-header allows the client to specify what additional communication protocols it supports and
+ * would like to use if the server finds it appropriate to switch protocols.
+ * The server MUST use the Upgrade header field within a 101 (Switching Protocols) response to indicate which
+ * protocol(s) are being switched.
+ * <p class='bcode'>
+ * 	Upgrade        = "Upgrade" ":" 1#product
+ * </p>
+ * <p>
+ * For example,
+ * <p class='bcode'>
+ * 	Upgrade: HTTP/2.0, SHTTP/1.3, IRC/6.9, RTA/x11
+ * </p>
+ * <p>
+ * The Upgrade header field is intended to provide a simple mechanism for transition from HTTP/1.1 to some other,
+ * incompatible protocol.
+ * It does so by allowing the client to advertise its desire to use another protocol, such as a later version of HTTP
+ * with a higher major version number, even though the current request has been made using HTTP/1.1.
+ * This eases the difficult transition between incompatible protocols by allowing the client to initiate a request in
+ * the more commonly supported protocol while indicating to the server that it would like to use a "better" protocol if
+ * available (where "better" is determined by the server, possibly according to the nature of the method and/or resource
+ * being requested).
+ * <p>
+ * The Upgrade header field only applies to switching application-layer protocols upon the existing transport-layer
+ * connection.
+ * Upgrade cannot be used to insist on a protocol change; its acceptance and use by the server is optional.
+ * The capabilities and nature of the application-layer communication after the protocol change is entirely dependent
+ * upon the new protocol chosen, although the first action after changing the protocol MUST be a response to the initial
+ * HTTP request containing the Upgrade header field.
+ * <p>
+ * The Upgrade header field only applies to the immediate connection.
+ * Therefore, the upgrade keyword MUST be supplied within a Connection header field (section 14.10) whenever Upgrade is
+ * present in an HTTP/1.1 message.
+ * <p>
+ * The Upgrade header field cannot be used to indicate a switch to a protocol on a different connection.
+ * For that purpose, it is more appropriate to use a 301, 302, 303, or 305 redirection response.
+ * <p>
+ * This specification only defines the protocol name "HTTP" for use by the family of Hypertext Transfer Protocols, as
+ * defined by the HTTP version rules of section 3.1 and future updates to this specification.
+ * Any token can be used as a protocol name; however, it will only be useful if both the client and server associate
+ * the name with the same protocol.
+ */
+public final class Upgrade extends HeaderStringArray {
+
+	/**
+	 * Returns a parsed <code>Upgrade</code> header.
+	 *
+	 * @param value The <code>Upgrade</code> header string.
+	 * @return The parsed <code>Upgrade</code> header, or <jk>null</jk> if the string was null.
+	 */
+	public static Upgrade forString(String value) {
+		if (value == null)
+			return null;
+		return new Upgrade(value);
+	}
+
+	private Upgrade(String value) {
+		super(value);
+	}
+}

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/fa4736b6/juneau-core/src/main/java/org/apache/juneau/http/UserAgent.java
----------------------------------------------------------------------
diff --git a/juneau-core/src/main/java/org/apache/juneau/http/UserAgent.java b/juneau-core/src/main/java/org/apache/juneau/http/UserAgent.java
new file mode 100644
index 0000000..39c49a4
--- /dev/null
+++ b/juneau-core/src/main/java/org/apache/juneau/http/UserAgent.java
@@ -0,0 +1,60 @@
+// ***************************************************************************************************************************
+// * Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements.  See the NOTICE file *
+// * distributed with this work for additional information regarding copyright ownership.  The ASF licenses this file        *
+// * to you under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance            *
+// * with the License.  You may obtain a copy of the License at                                                              *
+// *                                                                                                                         *
+// *  http://www.apache.org/licenses/LICENSE-2.0                                                                             *
+// *                                                                                                                         *
+// * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an  *
+// * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the License for the        *
+// * specific language governing permissions and limitations under the License.                                              *
+// ***************************************************************************************************************************
+package org.apache.juneau.http;
+
+/**
+ * Represents a parsed <l>User-Agent</l> HTTP request header.
+ * <p>
+ * The user agent string of the user agent.
+ *
+ * <h6 class='figure'>Example</h6>
+ * <p class='bcode'>
+ * 	User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:12.0) Gecko/20100101 Firefox/21.0
+ * </p>
+ *
+ * <h6 class='topic'>RFC2616 Specification</h6>
+ *
+ * The User-Agent request-header field contains information about the user agent originating the request.
+ * This is for statistical purposes, the tracing of protocol violations, and automated recognition of user agents for
+ * the sake of tailoring responses to avoid particular user agent limitations.
+ * User agents SHOULD include this field with requests.
+ * The field can contain multiple product tokens (section 3.8) and comments identifying the agent and any subproducts
+ * which form a significant part of the user agent.
+ * By convention, the product tokens are listed in order of their significance for identifying the application.
+ * <p class='bcode'>
+ * 	User-Agent     = "User-Agent" ":" 1*( product | comment )
+ * </p>
+ * <p>
+ * Example:
+ * <p class='bcode'>
+ * 	User-Agent: CERN-LineMode/2.15 libwww/2.17b3
+ * </p>
+ */
+public final class UserAgent extends HeaderString {
+
+	/**
+	 * Returns a parsed <code>User-Agent</code> header.
+	 *
+	 * @param value The <code>User-Agent</code> header string.
+	 * @return The parsed <code>User-Agent</code> header, or <jk>null</jk> if the string was null.
+	 */
+	public static UserAgent forString(String value) {
+		if (value == null)
+			return null;
+		return new UserAgent(value);
+	}
+
+	private UserAgent(String value) {
+		super(value);
+	}
+}

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/fa4736b6/juneau-core/src/main/java/org/apache/juneau/http/Vary.java
----------------------------------------------------------------------
diff --git a/juneau-core/src/main/java/org/apache/juneau/http/Vary.java b/juneau-core/src/main/java/org/apache/juneau/http/Vary.java
new file mode 100644
index 0000000..0bb3faf
--- /dev/null
+++ b/juneau-core/src/main/java/org/apache/juneau/http/Vary.java
@@ -0,0 +1,78 @@
+// ***************************************************************************************************************************
+// * Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements.  See the NOTICE file *
+// * distributed with this work for additional information regarding copyright ownership.  The ASF licenses this file        *
+// * to you under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance            *
+// * with the License.  You may obtain a copy of the License at                                                              *
+// *                                                                                                                         *
+// *  http://www.apache.org/licenses/LICENSE-2.0                                                                             *
+// *                                                                                                                         *
+// * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an  *
+// * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the License for the        *
+// * specific language governing permissions and limitations under the License.                                              *
+// ***************************************************************************************************************************
+package org.apache.juneau.http;
+
+/**
+ * Represents a parsed <l>Vary</l> HTTP response header.
+ * <p>
+ * Tells downstream proxies how to match future request headers to decide whether the cached response can be used rather
+ * than requesting a fresh one from the origin server.
+
+ *
+ * <h6 class='figure'>Example</h6>
+ * <p class='bcode'>
+ * 	Vary: *
+ * 	Vary: Accept-Language
+ * </p>
+ *
+ * <h6 class='topic'>RFC2616 Specification</h6>
+ *
+ * The Vary field value indicates the set of request-header fields that fully determines, while the response is fresh,
+ * whether a cache is permitted to use the response to reply to a subsequent request without revalidation.
+ * For uncacheable or stale responses, the Vary field value advises the user agent about the criteria that were used to
+ * select the representation.
+ * A Vary field value of "*" implies that a cache cannot determine from the request headers of a subsequent request
+ * whether this response is the appropriate representation.
+ * See section 13.6 for use of the Vary header field by caches.
+ * <p class='bcode'>
+ * 	Vary  = "Vary" ":" ( "*" | 1#field-name )
+ * </p>
+ * <p>
+ * An HTTP/1.1 server SHOULD include a Vary header field with any cacheable response that is subject to server-driven
+ * negotiation.
+ * Doing so allows a cache to properly interpret future requests on that resource and informs the user agent about the
+ * presence of negotiation on that resource.
+ * A server MAY include a Vary header field with a non-cacheable response that is subject to server-driven negotiation,
+ * since this might provide the user agent with useful information about the dimensions over which the response varies
+ * at the time of the response.
+ * <p>
+ * A Vary field value consisting of a list of field-names signals that the representation selected for the response is
+ * based on a selection algorithm which considers ONLY the listed request-header field values in selecting the most appropriate representation.
+ * A cache MAY assume that the same selection will be made for future requests with the same values for the listed
+ * field names, for the duration of time for which the response is fresh.
+ * <p>
+ * The field-names given are not limited to the set of standard request-header fields defined by this specification.
+ * Field names are case-insensitive.
+ * <p>
+ * A Vary field value of "*" signals that unspecified parameters not limited to the request-headers (e.g., the network
+ * address of the client), play a role in the selection of the response representation.
+ * The "*" value MUST NOT be generated by a proxy server; it may only be generated by an origin server.
+ */
+public final class Vary extends HeaderString {
+
+	/**
+	 * Returns a parsed <code>Vary</code> header.
+	 *
+	 * @param value The <code>Vary</code> header string.
+	 * @return The parsed <code>Vary</code> header, or <jk>null</jk> if the string was null.
+	 */
+	public static Vary forString(String value) {
+		if (value == null)
+			return null;
+		return new Vary(value);
+	}
+
+	private Vary(String value) {
+		super(value);
+	}
+}

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/fa4736b6/juneau-core/src/main/java/org/apache/juneau/http/Via.java
----------------------------------------------------------------------
diff --git a/juneau-core/src/main/java/org/apache/juneau/http/Via.java b/juneau-core/src/main/java/org/apache/juneau/http/Via.java
new file mode 100644
index 0000000..a280354
--- /dev/null
+++ b/juneau-core/src/main/java/org/apache/juneau/http/Via.java
@@ -0,0 +1,115 @@
+// ***************************************************************************************************************************
+// * Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements.  See the NOTICE file *
+// * distributed with this work for additional information regarding copyright ownership.  The ASF licenses this file        *
+// * to you under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance            *
+// * with the License.  You may obtain a copy of the License at                                                              *
+// *                                                                                                                         *
+// *  http://www.apache.org/licenses/LICENSE-2.0                                                                             *
+// *                                                                                                                         *
+// * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an  *
+// * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the License for the        *
+// * specific language governing permissions and limitations under the License.                                              *
+// ***************************************************************************************************************************
+package org.apache.juneau.http;
+
+/**
+ * Represents a parsed <l>Via</l> HTTP response header.
+ * <p>
+ * Informs the client of proxies through which the response was sent.
+ *
+ * <h6 class='figure'>Example</h6>
+ * <p class='bcode'>
+ * 	Via: 1.0 fred, 1.1 example.com (Apache/1.1)
+ * </p>
+ *
+ * Informs the client of proxies through which the response was sent.
+ * <p>
+ * <h6 class='figure'>Example</h6>
+ * <p class='bcode'>
+ * 	Via: 1.0 fred, 1.1 example.com (Apache/1.1)
+ * </p>
+ * <p>
+ * <h6 class='topic'>RFC2616 Specification</h6>
+ *
+ * The Via general-header field MUST be used by gateways and proxies to indicate the intermediate protocols and
+ * recipients between the user agent and the server on requests, and between the origin server and the client on
+ * responses.
+ * It is analogous to the "Received" field of RFC 822 and is intended to be used for tracking message forwards,
+ * avoiding request loops, and identifying the protocol capabilities of all senders along the request/response chain.
+ * <p class='bcode'>
+ * 	Via =  "Via" ":" 1#( received-protocol received-by [ comment ] )
+ * 	received-protocol = [ protocol-name "/" ] protocol-version
+ * 	protocol-name     = token
+ * 	protocol-version  = token
+ * 	received-by       = ( host [ ":" port ] ) | pseudonym
+ * 	pseudonym         = token
+ * </p>
+ * <p>
+ * The received-protocol indicates the protocol version of the message received by the server or client along each
+ * segment of the request/response chain.
+ * The received-protocol version is appended to the Via field value when the message is forwarded so that information
+ * about the protocol capabilities of upstream applications remains visible to all recipients.
+ * <p>
+ * The protocol-name is optional if and only if it would be "HTTP".
+ * The received-by field is normally the host and optional port number of a recipient server or client that subsequently
+ * forwarded the message.
+ * However, if the real host is considered to be sensitive information, it MAY be replaced by a pseudonym.
+ * If the port is not given, it MAY be assumed to be the default port of the received-protocol.
+ * <p>
+ * Multiple Via field values represents each proxy or gateway that has forwarded the message.
+ * Each recipient MUST append its information such that the end result is ordered according to the sequence of
+ * forwarding applications.
+ * <p>
+ * Comments MAY be used in the Via header field to identify the software of the recipient proxy or gateway, analogous
+ * to the User-Agent and Server header fields.
+ * However, all comments in the Via field are optional and MAY be removed by any recipient prior to forwarding the
+ * message.
+ * <p>
+ * For example, a request message could be sent from an HTTP/1.0 user agent to an internal proxy code-named "fred",
+ * which uses HTTP/1.1 to forward the request to a public proxy at nowhere.com, which completes the request by
+ * forwarding it to the origin server at www.ics.uci.edu.
+ * The request received by www.ics.uci.edu would then have the following Via header field:
+ * <p class='bcode'>
+ * 	Via: 1.0 fred, 1.1 nowhere.com (Apache/1.1)
+ * </p>
+ * <p>
+ * Proxies and gateways used as a portal through a network firewall SHOULD NOT, by default, forward the names and ports
+ * of hosts within the firewall region.
+ * This information SHOULD only be propagated if explicitly enabled.
+ * If not enabled, the received-by host of any host behind the firewall SHOULD be replaced by an appropriate pseudonym
+ * for that host.
+ * <p>
+ * For organizations that have strong privacy requirements for hiding internal structures, a proxy MAY combine an
+ * ordered subsequence of Via header field entries with identical received-protocol values into a single such entry.
+ * For example...
+ * <p class='bcode'>
+ * 	Via: 1.0 ricky, 1.1 ethel, 1.1 fred, 1.0 lucy
+ * </p>
+ * <p>
+ * ...could be collapsed to...
+ * <p class='bcode'>
+ * 	Via: 1.0 ricky, 1.1 mertz, 1.0 lucy
+ * </p>
+ * <p>
+ * Applications SHOULD NOT combine multiple entries unless they are all under the same organizational control and the
+ * hosts have already been replaced by pseudonyms.
+ * Applications MUST NOT combine entries which have different received-protocol values.
+ */
+public final class Via extends HeaderStringArray {
+
+	/**
+	 * Returns a parsed <code>Via</code> header.
+	 *
+	 * @param value The <code>Via</code> header string.
+	 * @return The parsed <code>Via</code> header, or <jk>null</jk> if the string was null.
+	 */
+	public static Via forString(String value) {
+		if (value == null)
+			return null;
+		return new Via(value);
+	}
+
+	private Via(String value) {
+		super(value);
+	}
+}

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/fa4736b6/juneau-core/src/main/java/org/apache/juneau/http/Warning.java
----------------------------------------------------------------------
diff --git a/juneau-core/src/main/java/org/apache/juneau/http/Warning.java b/juneau-core/src/main/java/org/apache/juneau/http/Warning.java
new file mode 100644
index 0000000..2267fe7
--- /dev/null
+++ b/juneau-core/src/main/java/org/apache/juneau/http/Warning.java
@@ -0,0 +1,123 @@
+// ***************************************************************************************************************************
+// * Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements.  See the NOTICE file *
+// * distributed with this work for additional information regarding copyright ownership.  The ASF licenses this file        *
+// * to you under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance            *
+// * with the License.  You may obtain a copy of the License at                                                              *
+// *                                                                                                                         *
+// *  http://www.apache.org/licenses/LICENSE-2.0                                                                             *
+// *                                                                                                                         *
+// * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an  *
+// * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the License for the        *
+// * specific language governing permissions and limitations under the License.                                              *
+// ***************************************************************************************************************************
+package org.apache.juneau.http;
+
+/**
+ * Represents a parsed <l>Warning</l> HTTP request/response header.
+ * <p>
+ * A general warning about possible problems with the entity body.
+ *
+ * <h6 class='figure'>Example</h6>
+ * <p class='bcode'>
+ * 	Warning: 199 Miscellaneous warning
+ * </p>
+ *
+ * <h6 class='topic'>RFC2616 Specification</h6>
+ *
+ * The Warning general-header field is used to carry additional information about the status or transformation of a
+ * message which might not be reflected in the message.
+ * This information is typically used to warn about a possible lack of semantic transparency from caching operations
+ * or transformations applied to the entity body of the message.
+ * <p>
+ * Warning headers are sent with responses using:
+ * <p class='bcode'>
+ * 	Warning    = "Warning" ":" 1#warning-value
+ * 	warning-value = warn-code SP warn-agent SP warn-text
+ * 	                                      [SP warn-date]
+ * 	warn-code  = 3DIGIT
+ * 	warn-agent = ( host [ ":" port ] ) | pseudonym
+ * 	                ; the name or pseudonym of the server adding
+ * 	                ; the Warning header, for use in debugging
+ * 	warn-text  = quoted-string
+ * 	warn-date  = <"> HTTP-date <">
+ * </p>
+ * <p>
+ * A response MAY carry more than one Warning header.
+ * <p>
+ * The warn-text SHOULD be in a natural language and character set that is most likely to be intelligible to the human
+ * user receiving the response.
+ * This decision MAY be based on any available knowledge, such as the location of the cache or user, the
+ * Accept-Language field in a request, the Content-Language field in a response, etc.
+ * The default language is English and the default character set is ISO-8859-1.
+ * <p>
+ * If a character set other than ISO-8859-1 is used, it MUST be encoded in the warn-text using the method described in
+ * RFC 2047.
+ * <p>
+ * Warning headers can in general be applied to any message, however some specific warn-codes are specific to caches
+ * and can only be applied to response messages.
+ * New Warning headers SHOULD be added after any existing Warning headers.
+ * A cache MUST NOT delete any Warning header that it received with a message.
+ * However, if a cache successfully validates a cache entry, it SHOULD remove any Warning headers previously attached
+ * to that entry except as specified for specific Warning codes.
+ * It MUST then add any Warning headers received in the validating response.
+ * In other words, Warning headers are those that would be attached to the most recent relevant response.
+ * <p>
+ * When multiple Warning headers are attached to a response, the user agent ought to inform the user of as many of them
+ * as possible, in the order that they appear in the response.
+ * If it is not possible to inform the user of all of the warnings, the user agent SHOULD follow these heuristics:
+ * <ul>
+ * 	<li>Warnings that appear early in the response take priority over those appearing later in the response.
+ * 	<li>Warnings in the user's preferred character set take priority over warnings in other character sets but with
+ * identical warn-codes and warn-agents.
+ * </ul>
+ * Systems that generate multiple Warning headers SHOULD order them with this user agent behavior in mind.
+ * <p>
+ * Requirements for the behavior of caches with respect to Warnings are stated in section 13.1.2.
+ * <p>
+ * This is a list of the currently-defined warn-codes, each with a recommended warn-text in English, and a description
+ * of its meaning.
+ * <ul>
+ * 	<li>110 Response is stale MUST be included whenever the returned response is stale.
+ * 	<li>111 Revalidation failed MUST be included if a cache returns a stale response because an attempt to revalidate
+ * 		the response failed, due to an inability to reach the server.
+ * 	<li>112 Disconnected operation SHOULD be included if the cache is intentionally disconnected from the rest of the
+ * 		network for a period of time.
+ * 	<li>113 Heuristic expiration MUST be included if the cache heuristically chose a freshness lifetime greater than
+ * 		24 hours and the response's age is greater than 24 hours.
+ * 	<li>199 Miscellaneous warning The warning text MAY include arbitrary information to be presented to a human user,
+ * 		or logged. A system receiving this warning MUST NOT take any automated action, besides presenting the warning
+ * 		to the user.
+ * 	<li>214 Transformation applied MUST be added by an intermediate cache or proxy if it applies any transformation
+ * 		changing the content-coding (as specified in the Content-Encoding header) or media-type (as specified in the
+ * 		Content-Type header) of the response, or the entity-body of the response, unless this Warning code already
+ * 		appears in the response.
+ * 	<li>299 Miscellaneous persistent warning The warning text MAY include arbitrary information to be presented to a
+ * 		human user, or logged. A system receiving this warning MUST NOT take any automated action.
+ * </ul>
+ * If an implementation sends a message with one or more Warning headers whose version is HTTP/1.0 or lower, then the
+ * sender MUST include in each warning-value a warn-date that matches the date in the response.
+ * <p>
+ * If an implementation receives a message with a warning-value that includes a warn-date, and that warn-date is
+ * different from the Date value in the response, then that warning-value MUST be deleted from the message before
+ * storing, forwarding, or using it.
+ * (This prevents bad consequences of naive caching of Warning header fields.)
+ * If all of the warning-values are deleted for this reason, the Warning header MUST be deleted as well.
+ */
+public final class Warning extends HeaderString {
+
+	/**
+	 * Returns a parsed <code>Warning</code> header.
+	 *
+	 * @param value The <code>Warning</code> header string.
+	 * @return The parsed <code>Warning</code> header, or <jk>null</jk> if the string was null.
+	 */
+	public static Warning forString(String value) {
+		if (value == null)
+			return null;
+		return new Warning(value);
+	}
+
+	private Warning(String value) {
+		super(value);
+	}
+}

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/fa4736b6/juneau-core/src/main/java/org/apache/juneau/http/WwwAuthenticate.java
----------------------------------------------------------------------
diff --git a/juneau-core/src/main/java/org/apache/juneau/http/WwwAuthenticate.java b/juneau-core/src/main/java/org/apache/juneau/http/WwwAuthenticate.java
new file mode 100644
index 0000000..448ced9
--- /dev/null
+++ b/juneau-core/src/main/java/org/apache/juneau/http/WwwAuthenticate.java
@@ -0,0 +1,56 @@
+// ***************************************************************************************************************************
+// * Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements.  See the NOTICE file *
+// * distributed with this work for additional information regarding copyright ownership.  The ASF licenses this file        *
+// * to you under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance            *
+// * with the License.  You may obtain a copy of the License at                                                              *
+// *                                                                                                                         *
+// *  http://www.apache.org/licenses/LICENSE-2.0                                                                             *
+// *                                                                                                                         *
+// * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an  *
+// * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the License for the        *
+// * specific language governing permissions and limitations under the License.                                              *
+// ***************************************************************************************************************************
+package org.apache.juneau.http;
+
+/**
+ * Represents a parsed <l>WWW-Authenticate </l> HTTP response header.
+ * <p>
+ * Indicates the authentication scheme that should be used to access the requested entity.
+ *
+ * <h6 class='figure'>Example</h6>
+ * <p class='bcode'>
+ * 	WWW-Authenticate: Basic
+ * </p>
+ *
+ * <h6 class='topic'>RFC2616 Specification</h6>
+ *
+ * The WWW-Authenticate response-header field MUST be included in 401 (Unauthorized) response messages.
+ * The field value consists of at least one challenge that indicates the authentication scheme(s) and parameters
+ * applicable to the Request-URI.
+ * <p class='bcode'>
+ * 	WWW-Authenticate  = "WWW-Authenticate" ":" 1#challenge
+ * </p>
+ * <p>
+ * The HTTP access authentication process is described in "HTTP Authentication: Basic and Digest Access Authentication".
+ * User agents are advised to take special care in parsing the WWW-Authenticate field value as it might contain more
+ * than one challenge, or if more than one WWW-Authenticate header field is provided, the contents of a challenge
+ * itself can contain a comma-separated list of authentication parameters.
+ */
+public final class WwwAuthenticate extends HeaderString {
+
+	/**
+	 * Returns a parsed <code>WWW-Authenticate</code> header.
+	 *
+	 * @param value The <code>WWW-Authenticate</code> header string.
+	 * @return The parsed <code>WWW-Authenticate</code> header, or <jk>null</jk> if the string was null.
+	 */
+	public static WwwAuthenticate forString(String value) {
+		if (value == null)
+			return null;
+		return new WwwAuthenticate(value);
+	}
+
+	private WwwAuthenticate(String value) {
+		super(value);
+	}
+}

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/fa4736b6/juneau-core/src/main/java/org/apache/juneau/internal/Cache.java
----------------------------------------------------------------------
diff --git a/juneau-core/src/main/java/org/apache/juneau/internal/Cache.java b/juneau-core/src/main/java/org/apache/juneau/internal/Cache.java
new file mode 100644
index 0000000..2b31062
--- /dev/null
+++ b/juneau-core/src/main/java/org/apache/juneau/internal/Cache.java
@@ -0,0 +1,81 @@
+// ***************************************************************************************************************************
+// * Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements.  See the NOTICE file *
+// * distributed with this work for additional information regarding copyright ownership.  The ASF licenses this file        *
+// * to you under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance            *
+// * with the License.  You may obtain a copy of the License at                                                              *
+// *                                                                                                                         *
+// *  http://www.apache.org/licenses/LICENSE-2.0                                                                             *
+// *                                                                                                                         *
+// * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an  *
+// * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the License for the        *
+// * specific language governing permissions and limitations under the License.                                              *
+// ***************************************************************************************************************************
+package org.apache.juneau.internal;
+
+import java.util.concurrent.*;
+
+/**
+ * Simple in-memory cache of objects.
+ * <p>
+ * Essentially just a wrapper around a ConcurrentHashMap.
+ *
+ * @param <K> The key type.
+ * @param <V> The value type.
+ */
+public class Cache<K,V> {
+	private final boolean nocache;
+	private final int maxSize;
+	private final ConcurrentHashMap<K,V> cache;
+
+	/**
+	 * Constructor.
+	 *
+	 * @param disabled If <jk>true</jk> then the cache is disabled.
+	 * @param maxSize The maximum size of the cache.  If this threshold is reached, the cache is flushed.
+	 */
+	public Cache(boolean disabled, int maxSize) {
+		this.nocache = disabled;
+		this.maxSize = maxSize;
+		if (! nocache)
+			cache = new ConcurrentHashMap<K,V>();
+		else
+			cache = null;
+	}
+
+	/**
+	 * Retrieves the value with the specified key from this cache.
+	 *
+	 * @param key The key.
+	 * @return The value, or <jk>null</jk> if the value is not in the cache, or the cache is disabled.
+	 */
+	public V get(K key) {
+		if (nocache)
+			return null;
+		return cache.get(key);
+	}
+
+	/**
+	 * Adds the value with the specified key to this cache.
+	 *
+	 * @param key The key.
+	 * @param value The value.
+	 * @return Either the value already in the cache if it already exists, or the same value passed in.
+	 * Always returns the same value if the cache is disabled.
+	 */
+	public V put(K key, V value) {
+		if (nocache)
+			return value;
+
+		// Prevent OOM in case of DDOS
+		if (cache.size() > maxSize)
+			cache.clear();
+
+		while (true) {
+			V v = cache.get(key);
+			if (v != null)
+				return v;
+			cache.putIfAbsent(key, value);
+			return value;
+		}
+	}
+}

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/fa4736b6/juneau-core/src/main/java/org/apache/juneau/internal/DateUtils.java
----------------------------------------------------------------------
diff --git a/juneau-core/src/main/java/org/apache/juneau/internal/DateUtils.java b/juneau-core/src/main/java/org/apache/juneau/internal/DateUtils.java
new file mode 100644
index 0000000..48565c4
--- /dev/null
+++ b/juneau-core/src/main/java/org/apache/juneau/internal/DateUtils.java
@@ -0,0 +1,186 @@
+// ***************************************************************************************************************************
+// * Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements.  See the NOTICE file *
+// * distributed with this work for additional information regarding copyright ownership.  The ASF licenses this file        *
+// * to you under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance            *
+// * with the License.  You may obtain a copy of the License at                                                              *
+// *                                                                                                                         *
+// *  http://www.apache.org/licenses/LICENSE-2.0                                                                             *
+// *                                                                                                                         *
+// * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an  *
+// * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the License for the        *
+// * specific language governing permissions and limitations under the License.                                              *
+// ***************************************************************************************************************************
+package org.apache.juneau.internal;
+
+import java.lang.ref.*;
+import java.text.*;
+import java.util.*;
+
+/**
+ * A utility class for parsing and formatting HTTP dates as used in cookies and
+ * other headers.  This class handles dates as defined by RFC 2616 section
+ * 3.3.1 as well as some other common non-standard formats.
+ * <p>
+ * This class was copied from HttpClient 4.3.
+ */
+public final class DateUtils {
+
+	/**
+	 * Date format pattern used to parse HTTP date headers in RFC 1123 format.
+	 */
+	public static final String PATTERN_RFC1123 = "EEE, dd MMM yyyy HH:mm:ss zzz";
+
+	/**
+	 * Date format pattern used to parse HTTP date headers in RFC 1036 format.
+	 */
+	public static final String PATTERN_RFC1036 = "EEE, dd-MMM-yy HH:mm:ss zzz";
+
+	/**
+	 * Date format pattern used to parse HTTP date headers in ANSI C <code>asctime()</code> format.
+	 */
+	public static final String PATTERN_ASCTIME = "EEE MMM d HH:mm:ss yyyy";
+	private static final String[] DEFAULT_PATTERNS = new String[] { PATTERN_RFC1123, PATTERN_RFC1036, PATTERN_ASCTIME };
+	private static final Date DEFAULT_TWO_DIGIT_YEAR_START;
+	private static final TimeZone GMT = TimeZone.getTimeZone("GMT");
+	static {
+		final Calendar calendar = Calendar.getInstance();
+		calendar.setTimeZone(GMT);
+		calendar.set(2000, Calendar.JANUARY, 1, 0, 0, 0);
+		calendar.set(Calendar.MILLISECOND, 0);
+		DEFAULT_TWO_DIGIT_YEAR_START = calendar.getTime();
+	}
+
+	/**
+	 * Parses a date value. The formats used for parsing the date value are retrieved from the default http params.
+	 *
+	 * @param dateValue the date value to parse
+	 * @return the parsed date or null if input could not be parsed
+	 */
+	public static Date parseDate(final String dateValue) {
+		return parseDate(dateValue, null, null);
+	}
+
+	/**
+	 * Parses the date value using the given date formats.
+	 *
+	 * @param dateValue the date value to parse
+	 * @param dateFormats the date formats to use
+	 *
+	 * @return the parsed date or null if input could not be parsed
+	 */
+	public static Date parseDate(final String dateValue, final String[] dateFormats) {
+		return parseDate(dateValue, dateFormats, null);
+	}
+
+	/**
+	 * Parses the date value using the given date formats.
+	 *
+	 * @param dateValue the date value to parse
+	 * @param dateFormats the date formats to use
+	 * @param startDate During parsing, two digit years will be placed in the range <code>startDate</code> to
+	 * 	<code>startDate + 100 years</code>. This value may be <code>null</code>. When
+	 * 	<code>null</code> is given as a parameter, year <code>2000</code> will be used.
+	 *
+	 * @return the parsed date or null if input could not be parsed
+	 */
+	public static Date parseDate(final String dateValue, final String[] dateFormats, final Date startDate) {
+		final String[] localDateFormats = dateFormats != null ? dateFormats : DEFAULT_PATTERNS;
+		final Date localStartDate = startDate != null ? startDate : DEFAULT_TWO_DIGIT_YEAR_START;
+		String v = dateValue;
+		// trim single quotes around date if present
+		// see issue #5279
+		if (v.length() > 1 && v.startsWith("'") && v.endsWith("'")) {
+			v = v.substring(1, v.length() - 1);
+		}
+		for (final String dateFormat : localDateFormats) {
+			final SimpleDateFormat dateParser = DateFormatHolder.formatFor(dateFormat);
+			dateParser.set2DigitYearStart(localStartDate);
+			final ParsePosition pos = new ParsePosition(0);
+			final Date result = dateParser.parse(v, pos);
+			if (pos.getIndex() != 0) {
+				return result;
+			}
+		}
+		return null;
+	}
+
+	/**
+	 * Formats the given date according to the RFC 1123 pattern.
+	 *
+	 * @param date The date to format.
+	 * @return An RFC 1123 formatted date string.
+	 *
+	 * @see #PATTERN_RFC1123
+	 */
+	public static String formatDate(final Date date) {
+		return formatDate(date, PATTERN_RFC1123);
+	}
+
+	/**
+	 * Formats the given date according to the specified pattern. The pattern must conform to that used by the
+	 * {@link SimpleDateFormat simple date format} class.
+	 *
+	 * @param date The date to format.
+	 * @param pattern The pattern to use for formatting the date.
+	 * @return A formatted date string.
+	 * @throws IllegalArgumentException If the given date pattern is invalid.
+	 * @see SimpleDateFormat
+	 */
+	public static String formatDate(final Date date, final String pattern) {
+		final SimpleDateFormat formatter = DateFormatHolder.formatFor(pattern);
+		return formatter.format(date);
+	}
+
+	/**
+	 * Clears thread-local variable containing {@link java.text.DateFormat} cache.
+	 */
+	public static void clearThreadLocal() {
+		DateFormatHolder.clearThreadLocal();
+	}
+
+	/** This class should not be instantiated. */
+	private DateUtils() {
+	}
+
+	/**
+	 * A factory for {@link SimpleDateFormat}s. The instances are stored in a threadlocal way because SimpleDateFormat
+	 * is not threadsafe as noted in {@link SimpleDateFormat its javadoc}.
+	 *
+	 */
+	final static class DateFormatHolder {
+		private static final ThreadLocal<SoftReference<Map<String,SimpleDateFormat>>> THREADLOCAL_FORMATS = new ThreadLocal<SoftReference<Map<String,SimpleDateFormat>>>() {
+			@Override
+			protected SoftReference<Map<String,SimpleDateFormat>> initialValue() {
+				return new SoftReference<Map<String,SimpleDateFormat>>(new HashMap<String,SimpleDateFormat>());
+			}
+		};
+
+		/**
+		 * creates a {@link SimpleDateFormat} for the requested format string.
+		 *
+		 * @param pattern a non-<code>null</code> format String according to {@link SimpleDateFormat}. The format is not
+		 * 	checked against <code>null</code> since all paths go through {@link DateUtils}.
+		 * @return the requested format. This simple dateformat should not be used to
+		 * 	{@link SimpleDateFormat#applyPattern(String) apply} to a different pattern.
+		 */
+		public static SimpleDateFormat formatFor(final String pattern) {
+			final SoftReference<Map<String,SimpleDateFormat>> ref = THREADLOCAL_FORMATS.get();
+			Map<String,SimpleDateFormat> formats = ref.get();
+			if (formats == null) {
+				formats = new HashMap<String,SimpleDateFormat>();
+				THREADLOCAL_FORMATS.set(new SoftReference<Map<String,SimpleDateFormat>>(formats));
+			}
+			SimpleDateFormat format = formats.get(pattern);
+			if (format == null) {
+				format = new SimpleDateFormat(pattern, Locale.US);
+				format.setTimeZone(TimeZone.getTimeZone("GMT"));
+				formats.put(pattern, format);
+			}
+			return format;
+		}
+
+		public static void clearThreadLocal() {
+			THREADLOCAL_FORMATS.remove();
+		}
+	}
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/fa4736b6/juneau-core/src/main/java/org/apache/juneau/internal/StringUtils.java
----------------------------------------------------------------------
diff --git a/juneau-core/src/main/java/org/apache/juneau/internal/StringUtils.java b/juneau-core/src/main/java/org/apache/juneau/internal/StringUtils.java
index bee95d9..8d324fe 100644
--- a/juneau-core/src/main/java/org/apache/juneau/internal/StringUtils.java
+++ b/juneau-core/src/main/java/org/apache/juneau/internal/StringUtils.java
@@ -1316,4 +1316,20 @@ public final class StringUtils {
 		}
 		return 0;
 	}
+
+	/**
+	 * Returns the character at the specified index in the string without throwing exceptions.
+	 *
+	 * @param s The string.
+	 * @param i The index position.
+	 * @return The character at the specified index, or <code>0</code> if the index is out-of-range or the string
+	 * 	is <jk>null</jk>.
+	 */
+	public static char charAt(String s, int i) {
+		if (s == null)
+			return 0;
+		if (i < 0 || i >= s.length())
+			return 0;
+		return s.charAt(i);
+	}
 }

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/fa4736b6/juneau-core/src/main/java/org/apache/juneau/xml/XmlParser.java
----------------------------------------------------------------------
diff --git a/juneau-core/src/main/java/org/apache/juneau/xml/XmlParser.java b/juneau-core/src/main/java/org/apache/juneau/xml/XmlParser.java
index 9c381b5..f4a4559 100644
--- a/juneau-core/src/main/java/org/apache/juneau/xml/XmlParser.java
+++ b/juneau-core/src/main/java/org/apache/juneau/xml/XmlParser.java
@@ -20,6 +20,7 @@ import java.lang.reflect.*;
 import java.util.*;
 
 import javax.xml.stream.*;
+import javax.xml.stream.Location;
 
 import org.apache.juneau.*;
 import org.apache.juneau.annotation.*;


[4/4] incubator-juneau git commit: Add HTTP header classes.

Posted by ja...@apache.org.
Add HTTP header classes.

Project: http://git-wip-us.apache.org/repos/asf/incubator-juneau/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-juneau/commit/fa4736b6
Tree: http://git-wip-us.apache.org/repos/asf/incubator-juneau/tree/fa4736b6
Diff: http://git-wip-us.apache.org/repos/asf/incubator-juneau/diff/fa4736b6

Branch: refs/heads/master
Commit: fa4736b6df552a5fd4dc624b51d4ae7431dbfcda
Parents: de98f18
Author: JamesBognar <ja...@apache.org>
Authored: Sat May 6 12:24:28 2017 -0400
Committer: JamesBognar <ja...@apache.org>
Committed: Sat May 6 12:24:28 2017 -0400

----------------------------------------------------------------------
 .../juneau/https/AcceptExtensionsTest.java      |  18 +-
 .../java/org/apache/juneau/BeanContext.java     |   2 +-
 .../java/org/apache/juneau/http/Accept.java     | 220 +++++++--------
 .../org/apache/juneau/http/AcceptCharset.java   |  82 ++++++
 .../org/apache/juneau/http/AcceptEncoding.java  | 181 +++++-------
 .../org/apache/juneau/http/AcceptLanguage.java  | 110 ++++++++
 .../org/apache/juneau/http/AcceptRanges.java    |  69 +++++
 .../main/java/org/apache/juneau/http/Age.java   |  64 +++++
 .../main/java/org/apache/juneau/http/Allow.java |  72 +++++
 .../org/apache/juneau/http/Authorization.java   |  78 ++++++
 .../org/apache/juneau/http/CacheControl.java    | 102 +++++++
 .../java/org/apache/juneau/http/Connection.java | 106 +++++++
 .../java/org/apache/juneau/http/Constants.java  |  21 ++
 .../org/apache/juneau/http/ContentEncoding.java |  74 +++++
 .../apache/juneau/http/ContentEncodingEnum.java |  34 +++
 .../org/apache/juneau/http/ContentLanguage.java |  78 ++++++
 .../org/apache/juneau/http/ContentLength.java   |  67 +++++
 .../org/apache/juneau/http/ContentLocation.java |  72 +++++
 .../org/apache/juneau/http/ContentRange.java    | 126 +++++++++
 .../org/apache/juneau/http/ContentType.java     |  58 ++--
 .../main/java/org/apache/juneau/http/Date.java  |  83 ++++++
 .../main/java/org/apache/juneau/http/ETag.java  |  58 ++++
 .../org/apache/juneau/http/EntityValidator.java |  72 +++++
 .../java/org/apache/juneau/http/Expect.java     |  73 +++++
 .../java/org/apache/juneau/http/Expires.java    |  80 ++++++
 .../main/java/org/apache/juneau/http/From.java  |  72 +++++
 .../java/org/apache/juneau/http/HeaderDate.java |  51 ++++
 .../juneau/http/HeaderEntityValidator.java      |  47 ++++
 .../juneau/http/HeaderEntityValidatorArray.java |  55 ++++
 .../java/org/apache/juneau/http/HeaderEnum.java |  70 +++++
 .../org/apache/juneau/http/HeaderInteger.java   |  59 ++++
 .../apache/juneau/http/HeaderRangeArray.java    |  74 +++++
 .../org/apache/juneau/http/HeaderString.java    |  72 +++++
 .../apache/juneau/http/HeaderStringArray.java   |  80 ++++++
 .../java/org/apache/juneau/http/HeaderUri.java  |  62 +++++
 .../main/java/org/apache/juneau/http/Host.java  |  75 +++++
 .../java/org/apache/juneau/http/IfMatch.java    |  90 ++++++
 .../org/apache/juneau/http/IfModifiedSince.java |  92 +++++++
 .../org/apache/juneau/http/IfNoneMatch.java     |  95 +++++++
 .../java/org/apache/juneau/http/IfRange.java    |  95 +++++++
 .../apache/juneau/http/IfUnmodifiedSince.java   |  66 +++++
 .../org/apache/juneau/http/LastModified.java    |  74 +++++
 .../java/org/apache/juneau/http/Location.java   |  63 +++++
 .../org/apache/juneau/http/MaxForwards.java     |  65 +++++
 .../java/org/apache/juneau/http/Pragma.java     |  71 +++++
 .../apache/juneau/http/ProxyAuthenticate.java   |  58 ++++
 .../apache/juneau/http/ProxyAuthorization.java  |  60 ++++
 .../main/java/org/apache/juneau/http/Range.java | 136 +++++++++
 .../java/org/apache/juneau/http/Referer.java    |  65 +++++
 .../java/org/apache/juneau/http/RetryAfter.java |  94 +++++++
 .../java/org/apache/juneau/http/Server.java     |  65 +++++
 .../org/apache/juneau/http/StringRange.java     | 276 +++++++++++++++++++
 .../main/java/org/apache/juneau/http/TE.java    |  97 +++++++
 .../java/org/apache/juneau/http/Trailer.java    |  65 +++++
 .../apache/juneau/http/TransferEncoding.java    |  64 +++++
 .../java/org/apache/juneau/http/TypeRange.java  | 276 -------------------
 .../java/org/apache/juneau/http/Upgrade.java    |  84 ++++++
 .../java/org/apache/juneau/http/UserAgent.java  |  60 ++++
 .../main/java/org/apache/juneau/http/Vary.java  |  78 ++++++
 .../main/java/org/apache/juneau/http/Via.java   | 115 ++++++++
 .../java/org/apache/juneau/http/Warning.java    | 123 +++++++++
 .../org/apache/juneau/http/WwwAuthenticate.java |  56 ++++
 .../java/org/apache/juneau/internal/Cache.java  |  81 ++++++
 .../org/apache/juneau/internal/DateUtils.java   | 186 +++++++++++++
 .../org/apache/juneau/internal/StringUtils.java |  16 ++
 .../java/org/apache/juneau/xml/XmlParser.java   |   1 +
 66 files changed, 4939 insertions(+), 545 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/fa4736b6/juneau-core-test/src/test/java/org/apache/juneau/https/AcceptExtensionsTest.java
----------------------------------------------------------------------
diff --git a/juneau-core-test/src/test/java/org/apache/juneau/https/AcceptExtensionsTest.java b/juneau-core-test/src/test/java/org/apache/juneau/https/AcceptExtensionsTest.java
index be8b0f0..6a7b0d3 100644
--- a/juneau-core-test/src/test/java/org/apache/juneau/https/AcceptExtensionsTest.java
+++ b/juneau-core-test/src/test/java/org/apache/juneau/https/AcceptExtensionsTest.java
@@ -32,7 +32,7 @@ public class AcceptExtensionsTest {
 		MediaTypeRange mr;
 		
 		accept = Accept.forString("text/json");
-		mr = accept.getMediaRanges().get(0);
+		mr = accept.asRanges().get(0);
 		assertTextEquals("text/json", mr);
 		assertTextEquals("text/json", mr.getMediaType());
 		assertObjectEquals("{}", mr.getMediaType().getParameters());
@@ -40,7 +40,7 @@ public class AcceptExtensionsTest {
 		assertObjectEquals("{}", mr.getExtensions());
 
 		accept = Accept.forString("foo,bar");
-		mr = accept.getMediaRanges().get(0);
+		mr = accept.asRanges().get(0);
 		assertTextEquals("foo", mr);
 		assertTextEquals("foo", mr.getMediaType());
 		assertObjectEquals("{}", mr.getMediaType().getParameters());
@@ -48,7 +48,7 @@ public class AcceptExtensionsTest {
 		assertObjectEquals("{}", mr.getExtensions());
 
 		accept = Accept.forString(" foo , bar ");
-		mr = accept.getMediaRanges().get(0);
+		mr = accept.asRanges().get(0);
 		assertTextEquals("foo", mr);
 		assertTextEquals("foo", mr.getMediaType());
 		assertObjectEquals("{}", mr.getMediaType().getParameters());
@@ -56,7 +56,7 @@ public class AcceptExtensionsTest {
 		assertObjectEquals("{}", mr.getExtensions());
 
 		accept = Accept.forString("text/json;a=1;q=0.9;b=2");
-		mr = accept.getMediaRanges().get(0);
+		mr = accept.asRanges().get(0);
 		assertTextEquals("text/json;a=1;q=0.9;b=2", mr);
 		assertTextEquals("text/json;a=1", mr.getMediaType());
 		assertObjectEquals("{a:['1']}", mr.getMediaType().getParameters());
@@ -64,7 +64,7 @@ public class AcceptExtensionsTest {
 		assertObjectEquals("{b:['2']}", mr.getExtensions());
 		
 		accept = Accept.forString("text/json;a=1;a=2;q=0.9;b=3;b=4");
-		mr = accept.getMediaRanges().get(0);
+		mr = accept.asRanges().get(0);
 		assertTextEquals("text/json;a=1;a=2;q=0.9;b=3;b=4", mr);
 		assertTextEquals("text/json;a=1;a=2", mr.getMediaType());
 		assertObjectEquals("{a:['1','2']}", mr.getMediaType().getParameters());
@@ -72,7 +72,7 @@ public class AcceptExtensionsTest {
 		assertObjectEquals("{b:['3','4']}", mr.getExtensions());
 
 		accept = Accept.forString("text/json;a=1");
-		mr = accept.getMediaRanges().get(0);
+		mr = accept.asRanges().get(0);
 		assertTextEquals("text/json;a=1", mr);
 		assertTextEquals("text/json;a=1", mr.getMediaType());
 		assertObjectEquals("{a:['1']}", mr.getMediaType().getParameters());
@@ -80,7 +80,7 @@ public class AcceptExtensionsTest {
 		assertObjectEquals("{}", mr.getExtensions());
 
 		accept = Accept.forString("text/json;a=1;");
-		mr = accept.getMediaRanges().get(0);
+		mr = accept.asRanges().get(0);
 		assertTextEquals("text/json;a=1", mr);
 		assertTextEquals("text/json;a=1", mr.getMediaType());
 		assertObjectEquals("{a:['1']}", mr.getMediaType().getParameters());
@@ -88,7 +88,7 @@ public class AcceptExtensionsTest {
 		assertObjectEquals("{}", mr.getExtensions());
 		
 		accept = Accept.forString("text/json;q=0.9");
-		mr = accept.getMediaRanges().get(0);
+		mr = accept.asRanges().get(0);
 		assertTextEquals("text/json;q=0.9", mr);
 		assertTextEquals("text/json", mr.getMediaType());
 		assertObjectEquals("{}", mr.getMediaType().getParameters());
@@ -96,7 +96,7 @@ public class AcceptExtensionsTest {
 		assertObjectEquals("{}", mr.getExtensions());
 
 		accept = Accept.forString("text/json;q=0.9;");
-		mr = accept.getMediaRanges().get(0);
+		mr = accept.asRanges().get(0);
 		assertTextEquals("text/json;q=0.9", mr);
 		assertTextEquals("text/json", mr.getMediaType());
 		assertObjectEquals("{}", mr.getMediaType().getParameters());

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/fa4736b6/juneau-core/src/main/java/org/apache/juneau/BeanContext.java
----------------------------------------------------------------------
diff --git a/juneau-core/src/main/java/org/apache/juneau/BeanContext.java b/juneau-core/src/main/java/org/apache/juneau/BeanContext.java
index c5df1d1..33c1165 100644
--- a/juneau-core/src/main/java/org/apache/juneau/BeanContext.java
+++ b/juneau-core/src/main/java/org/apache/juneau/BeanContext.java
@@ -942,7 +942,7 @@ public class BeanContext extends Context {
 	 * If <jk>null</jk>, the system default locale is assumed.
 	 * @param timeZone The bean session timezone.
 	 * Typically used by time-sensitive {@link PojoSwap PojoSwaps} to provide timezone-specific output.
-	 * If <jk>null</jk> the system default timezone is assumed on {@link Date} objects, or the
+	 * If <jk>null</jk> the system default timezone is assumed on {@link java.util.Date} objects, or the
 	 * 	locale specified on {@link Calendar} objects are used.
 	 * @param mediaType The session media type (e.g. <js>"application/json"</js>).
 	 * @return A new session object.

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/fa4736b6/juneau-core/src/main/java/org/apache/juneau/http/Accept.java
----------------------------------------------------------------------
diff --git a/juneau-core/src/main/java/org/apache/juneau/http/Accept.java b/juneau-core/src/main/java/org/apache/juneau/http/Accept.java
index 5fabc73..48aa91a 100644
--- a/juneau-core/src/main/java/org/apache/juneau/http/Accept.java
+++ b/juneau-core/src/main/java/org/apache/juneau/http/Accept.java
@@ -12,24 +12,29 @@
 // ***************************************************************************************************************************
 package org.apache.juneau.http;
 
+import static org.apache.juneau.http.Constants.*;
+
 import java.util.*;
-import java.util.concurrent.*;
 
 import org.apache.juneau.internal.*;
 
 /**
- * Represents a parsed <code>Accept:</code> HTTP header.
+ * Represents a parsed <l>Accept</l> HTTP request header.
  * <p>
- * The formal RFC2616 header field definition is as follows:
+ * Content-Types that are acceptable for the response.
+ *
+ * <h6 class='figure'>Example</h6>
  * <p class='bcode'>
- * 	14.1 Accept
+ * 	Accept: text/plain
+ * </p>
+ *
+ * <h6 class='topic'>RFC2616 Specification</h6>
  *
- * 	The Accept request-header field can be used to specify certain media
- * 	types which are acceptable for the response. Accept headers can be
- * 	used to indicate that the request is specifically limited to a small
- * 	set of desired types, as in the case of a request for an in-line
- * 	image.
+ * The Accept request-header field can be used to specify certain media types which are acceptable for the response.
+ * Accept headers can be used to indicate that the request is specifically limited to a small set of desired types, as
+ * in the case of a request for an in-line image.
  *
+ * <p class='bcode'>
  * 	 Accept         = "Accept" ":
  * 							#( media-range [ accept-params ] )
  *
@@ -39,122 +44,111 @@ import org.apache.juneau.internal.*;
  * 							) *( ";" parameter )
  * 	 accept-params  = ";" "q" "=" qvalue *( accept-extension )
  * 	 accept-extension = ";" token [ "=" ( token | quoted-string ) ]
- *
- * 	The asterisk "*" character is used to group media types into ranges,
- * 	with "* /*" indicating all media types and "type/*" indicating all
- * 	subtypes of that type. The media-range MAY include media type
- * 	parameters that are applicable to that range.
- *
- * 	Each media-range MAY be followed by one or more accept-params,
- * 	beginning with the "q" parameter for indicating a relative quality
- * 	factor. The first "q" parameter (if any) separates the media-range
- * 	parameter(s) from the accept-params. Quality factors allow the user
- * 	or user agent to indicate the relative degree of preference for that
- * 	media-range, using the qvalue scale from 0 to 1 (section 3.9). The
- * 	default value is q=1.
- *
- * 	Note: Use of the "q" parameter name to separate media type
- * 	parameters from Accept extension parameters is due to historical
- * 	practice. Although this prevents any media type parameter named
- * 	"q" from being used with a media range, such an event is believed
- * 	to be unlikely given the lack of any "q" parameters in the IANA
- * 	media type registry and the rare usage of any media type
- * 	parameters in Accept. Future media types are discouraged from
- * 	registering any parameter named "q".
- *
- * 	The example
- *
- * 		Accept: audio/*; q=0.2, audio/basic
- *
- * 	SHOULD be interpreted as "I prefer audio/basic, but send me any audio
- * 	type if it is the best available after an 80% mark-down in quality."
- *
- * 	If no Accept header field is present, then it is assumed that the
- * 	client accepts all media types. If an Accept header field is present,
- * 	and if the server cannot send a response which is acceptable
- * 	according to the combined Accept field value, then the server SHOULD
- * 	send a 406 (not acceptable) response.
- *
- * 	A more elaborate example is
- *
- * 	    Accept: text/plain; q=0.5, text/html,
- * 	            text/x-dvi; q=0.8, text/x-c
- *
- * 	Verbally, this would be interpreted as "text/html and text/x-c are
- * 	the preferred media types, but if they do not exist, then send the
- * 	text/x-dvi entity, and if that does not exist, send the text/plain
- * 	entity."
- *
- * 	Media ranges can be overridden by more specific media ranges or
- * 	specific media types. If more than one media range applies to a given
- * 	type, the most specific reference has precedence. For example,
- *
- * 	    Accept: text/ *, text/html, text/html;level=1, * /*
- *
- * 	have the following precedence:
- *
- * 	    1) text/html;level=1
- * 	    2) text/html
- * 	    3) text/*
- * 	    4) * /*
- *
- * 	The media type quality factor associated with a given type is
- * 	determined by finding the media range with the highest precedence
- * 	which matches that type. For example,
- *
- * 	    Accept: text/*;q=0.3, text/html;q=0.7, text/html;level=1,
- * 	            text/html;level=2;q=0.4, * /*;q=0.5
- *
- * 	would cause the following values to be associated:
- *
- * 	    text/html;level=1         = 1
- * 	    text/html                 = 0.7
- * 	    text/plain                = 0.3
- * 	    image/jpeg                = 0.5
- * 	    text/html;level=2         = 0.4
- * 	    text/html;level=3         = 0.7
- *
- * 	   Note: A user agent might be provided with a default set of quality
- * 	   values for certain media ranges. However, unless the user agent is
- * 	   a closed system which cannot interact with other rendering agents,
- * 	   this default set ought to be configurable by the user.
  * </p>
+ * <p>
+ * The asterisk "*" character is used to group media types into ranges, with "* /*" indicating all media types and
+ * "type/*" indicating all subtypes of that type.
+ * The media-range MAY include media type parameters that are applicable to that range.
+ * <p>
+ * Each media-range MAY be followed by one or more accept-params, beginning with the "q" parameter for indicating a
+ * relative quality factor.
+ * The first "q" parameter (if any) separates the media-range parameter(s) from the accept-params.
+ * Quality factors allow the user or user agent to indicate the relative degree of preference for that media-range,
+ * using the qvalue scale from 0 to 1 (section 3.9).
+ * The default value is q=1.
+ * <p>
+ * Note: Use of the "q" parameter name to separate media type parameters from Accept extension parameters is due to
+ * historical practice.
+ * Although this prevents any media type parameter named "q" from being used with a media range, such an event is
+ * believed to be unlikely given the lack of any "q" parameters in the IANA
+ * media type registry and the rare usage of any media type parameters in Accept.
+ * Future media types are discouraged from registering any parameter named "q".
+ * <p>
+ * The example
+ * <p class='bcode'>
+ * 	Accept: audio/*; q=0.2, audio/basic
+ * </p>
+ * <p>
+ * SHOULD be interpreted as "I prefer audio/basic, but send me any audio type if it is the best available after an 80%
+ * mark-down in quality."
+ * <p>
+ * If no Accept header field is present, then it is assumed that the client accepts all media types.
+ * <p>
+ * If an Accept header field is present, and if the server cannot send a response which is acceptable according to the
+ * combined Accept field value, then the server SHOULD send a 406 (not acceptable) response.
+ * <p>
+ * A more elaborate example is
+ * <p class='bcode'>
+ * 	Accept: text/plain; q=0.5, text/html,
+ * 	        text/x-dvi; q=0.8, text/x-c
+ * </p>
+ * <p>
+ * Verbally, this would be interpreted as "text/html and text/x-c are the preferred media types, but if they do not
+ * exist, then send the
+ * text/x-dvi entity, and if that does not exist, send the text/plain entity."
+ * <p>
+ * Media ranges can be overridden by more specific media ranges or specific media types.
+ * If more than one media range applies to a given type, the most specific reference has precedence.
+ * For example,
+ * <p class='bcode'>
+ * 	Accept: text/ *, text/html, text/html;level=1, * /*
+ * </p>
+ * <p>
+ * have the following precedence:
+ * <ol>
+ * 	<li>text/html;level=1
+ * 	<li>text/html
+ * 	<li>text/*
+ * 	<li>* /*
+ * </ol>
+ * <p>
+ * The media type quality factor associated with a given type is determined by finding the media range with the highest
+ * precedence which matches that type.
+ * For example,
+ * <p class='bcode'>
+ * 	Accept: text/*;q=0.3, text/html;q=0.7, text/html;level=1,
+ * 	        text/html;level=2;q=0.4, * /*;q=0.5
+ * </p>
+ * <p>
+ * would cause the following values to be associated:
+ * <p class='bcode'>
+ * 	text/html;level=1         = 1
+ * 	text/html                 = 0.7
+ * 	text/plain                = 0.3
+ * 	image/jpeg                = 0.5
+ * 	text/html;level=2         = 0.4
+ * 	text/html;level=3         = 0.7
+ * </p>
+ * <p>
+ * Note: A user agent might be provided with a default set of quality values for certain media ranges.
+ * However, unless the user agent is a closed system which cannot interact with other rendering agents, this default
+ * set ought to be configurable by the user.
  */
 public final class Accept {
 
-	private static final boolean nocache = Boolean.getBoolean("juneau.http.Accept.nocache");
-	private static final ConcurrentHashMap<String,Accept> cache = new ConcurrentHashMap<String,Accept>();
-
-	private final MediaTypeRange[] mediaRanges;
-	private final List<MediaTypeRange> mediaRangesList;
+	private static final Cache<String,Accept> cache = new Cache<String,Accept>(NOCACHE, CACHE_MAX_SIZE);
 
 	/**
 	 * Returns a parsed <code>Accept</code> header.
 	 *
-	 * @param s The <code>Accept</code> header string.
+	 * @param value The <code>Accept</code> header string.
 	 * @return The parsed <code>Accept</code> header, or <jk>null</jk> if the string was null.
 	 */
-	public static Accept forString(String s) {
-		if (s == null)
+	public static Accept forString(String value) {
+		if (value == null)
 			return null;
-
-		// Prevent OOM in case of DDOS
-		if (cache.size() > 1000)
-			cache.clear();
-
-		while (true) {
-			Accept a = cache.get(s);
-			if (a != null)
-				return a;
-			a = new Accept(s);
-			if (nocache)
-				return a;
-			cache.putIfAbsent(s, a);
-		}
+		Accept a = cache.get(value);
+		if (a == null)
+			a = cache.put(value, new Accept(value));
+		return a;
 	}
 
-	private Accept(String raw) {
-		this.mediaRanges = MediaTypeRange.parse(raw);
+
+	private final MediaTypeRange[] mediaRanges;
+	private final List<MediaTypeRange> mediaRangesList;
+
+	private Accept(String value) {
+		this.mediaRanges = MediaTypeRange.parse(value);
 		this.mediaRangesList = Collections.unmodifiableList(Arrays.asList(mediaRanges));
 	}
 
@@ -165,7 +159,7 @@ public final class Accept {
 	 *
 	 * @return An unmodifiable list of media ranges.
 	 */
-	public List<MediaTypeRange> getMediaRanges() {
+	public List<MediaTypeRange> asRanges() {
 		return mediaRangesList;
 	}
 

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/fa4736b6/juneau-core/src/main/java/org/apache/juneau/http/AcceptCharset.java
----------------------------------------------------------------------
diff --git a/juneau-core/src/main/java/org/apache/juneau/http/AcceptCharset.java b/juneau-core/src/main/java/org/apache/juneau/http/AcceptCharset.java
new file mode 100644
index 0000000..3792104
--- /dev/null
+++ b/juneau-core/src/main/java/org/apache/juneau/http/AcceptCharset.java
@@ -0,0 +1,82 @@
+// ***************************************************************************************************************************
+// * Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements.  See the NOTICE file *
+// * distributed with this work for additional information regarding copyright ownership.  The ASF licenses this file        *
+// * to you under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance            *
+// * with the License.  You may obtain a copy of the License at                                                              *
+// *                                                                                                                         *
+// *  http://www.apache.org/licenses/LICENSE-2.0                                                                             *
+// *                                                                                                                         *
+// * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an  *
+// * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the License for the        *
+// * specific language governing permissions and limitations under the License.                                              *
+// ***************************************************************************************************************************
+package org.apache.juneau.http;
+
+import static org.apache.juneau.http.Constants.*;
+
+import org.apache.juneau.internal.*;
+
+/**
+ * Represents a parsed <l>Accept-Charset</l> HTTP request header.
+ * <p>
+ * Character sets that are acceptable.
+ *
+ * <h6 class='figure'>Example</h6>
+ * <p class='bcode'>
+ * 	Accept-Charset: utf-8
+ * </p>
+ *
+ * <h6 class='topic'>RFC2616 Specification</h6>
+ *
+ * The Accept-Charset request-header field can be used to indicate what character sets are acceptable for the response.
+ * <p>
+ * This field allows clients capable of understanding more comprehensive or special- purpose character sets to signal
+ * that capability to a server which is capable of representing documents in those character sets.
+ * <p class='bcode'>
+ * 	Accept-Charset = "Accept-Charset" ":"
+ * 	                 1#( ( charset | "*" )[ ";" "q" "=" qvalue ] )
+ * </p>
+ * <p>
+ * Character set values are described in section 3.4. Each charset MAY be given an associated quality value which
+ * represents the user's preference for that charset.
+ * The default value is q=1.
+ * An example is...
+ * <p class='bcode'>
+ * 	Accept-Charset: iso-8859-5, unicode-1-1;q=0.8
+ * </p>
+ * <p>
+ * The special value "*", if present in the Accept-Charset field, matches every character set (including ISO-8859-1)
+ * which is not mentioned elsewhere in the Accept-Charset field.
+ * <p>
+ * If no "*" is present in an Accept-Charset field, then all character sets not explicitly mentioned get a quality
+ * value of 0, except for ISO-8859-1, which gets a quality value of 1 if not explicitly mentioned.
+ * <p>
+ * If no Accept-Charset header is present, the default is that any character set is acceptable.
+ * <p>
+ * If an Accept-Charset header is present, and if the server cannot send a response which is acceptable according to
+ * the Accept-Charset header, then the server SHOULD send an error response with the 406 (not acceptable) status code,
+ * though the sending of an unacceptable response is also allowed.
+ */
+public final class AcceptCharset extends HeaderRangeArray {
+
+	private static final Cache<String,AcceptCharset> cache = new Cache<String,AcceptCharset>(NOCACHE, CACHE_MAX_SIZE);
+
+	/**
+	 * Returns a parsed <code>Accept-Charset</code> header.
+	 *
+	 * @param value The <code>Accept-Charset</code> header string.
+	 * @return The parsed <code>Accept-Charset</code> header, or <jk>null</jk> if the string was null.
+	 */
+	public static AcceptCharset forString(String value) {
+		if (value == null)
+			return null;
+		AcceptCharset a = cache.get(value);
+		if (a == null)
+			a = cache.put(value, new AcceptCharset(value));
+		return a;
+	}
+
+	private AcceptCharset(String value) {
+		super(value);
+	}
+}

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/fa4736b6/juneau-core/src/main/java/org/apache/juneau/http/AcceptEncoding.java
----------------------------------------------------------------------
diff --git a/juneau-core/src/main/java/org/apache/juneau/http/AcceptEncoding.java b/juneau-core/src/main/java/org/apache/juneau/http/AcceptEncoding.java
index 8d83401..1502e57 100644
--- a/juneau-core/src/main/java/org/apache/juneau/http/AcceptEncoding.java
+++ b/juneau-core/src/main/java/org/apache/juneau/http/AcceptEncoding.java
@@ -12,142 +12,91 @@
 // ***************************************************************************************************************************
 package org.apache.juneau.http;
 
-import java.util.*;
-import java.util.concurrent.*;
+import static org.apache.juneau.http.Constants.*;
 
 import org.apache.juneau.internal.*;
 
 /**
- * Represents a parsed <code>Accept-Encoding:</code> HTTP header.
+ * Represents a parsed <l>Accept-Encoding</l> HTTP request header.
  * <p>
- * The formal RFC2616 header field definition is as follows:
- * <p class='bcode'>
- * 	The Accept-Encoding request-header field is similar to Accept, but restricts
- * 	the content-codings (section 3.5) that are acceptable in the response.
- *
- * 		Accept-Encoding  = "Accept-Encoding" ":"
- * 		                   1#( codings [ ";" "q" "=" qvalue ] )
- * 		codings          = ( content-coding | "*" )
- *
- * 	Examples of its use are:
- *
- * 		Accept-Encoding: compress, gzip
- * 		Accept-Encoding:
- * 		Accept-Encoding: *
- * 		Accept-Encoding: compress;q=0.5, gzip;q=1.0
- * 		Accept-Encoding: gzip;q=1.0, identity; q=0.5, *;q=0
- *
- * 	A server tests whether a content-coding is acceptable, according to an
- * 	Accept-Encoding field, using these rules:
+ * List of acceptable encodings.
  *
- * 	   1. If the content-coding is one of the content-codings listed in
- * 	      the Accept-Encoding field, then it is acceptable, unless it is
- * 	      accompanied by a qvalue of 0. (As defined in section 3.9, a
- * 	      qvalue of 0 means "not acceptable.")
- * 	   2. The special "*" symbol in an Accept-Encoding field matches any
- * 	      available content-coding not explicitly listed in the header
- * 	      field.
- * 	   3. If multiple content-codings are acceptable, then the acceptable
- * 	      content-coding with the highest non-zero qvalue is preferred.
- * 	   4. The "identity" content-coding is always acceptable, unless
- * 	      specifically refused because the Accept-Encoding field includes
- * 	      "identity;q=0", or because the field includes "*;q=0" and does
- * 	      not explicitly include the "identity" content-coding. If the
- * 	      Accept-Encoding field-value is empty, then only the "identity"
- * 	      encoding is acceptable.
+ * <h6 class='figure'>Example</h6>
+ * <p class='bcode'>
+ * 	Accept-Encoding: gzip, deflate
+ * </p>
  *
- * 	If an Accept-Encoding field is present in a request, and if the server cannot
- * 	send a response which is acceptable according to the Accept-Encoding header,
- * 	then the server SHOULD send an error response with the 406 (Not Acceptable) status code.
+ * <h6 class='topic'>RFC2616 Specification</h6>
  *
- * 	If no Accept-Encoding field is present in a request, the server MAY assume
- * 	that the client will accept any content coding. In this case, if "identity"
- * 	is one of the available content-codings, then the server SHOULD use the "identity"
- * 	content-coding, unless it has additional information that a different content-coding
- * 	is meaningful to the client.
+ * The Accept-Encoding request-header field is similar to Accept, but restricts the content-codings (section 3.5) that are acceptable in the response.
  *
- * 	      Note: If the request does not include an Accept-Encoding field,
- * 	      and if the "identity" content-coding is unavailable, then
- * 	      content-codings commonly understood by HTTP/1.0 clients (i.e.,
- * 	      "gzip" and "compress") are preferred; some older clients
- * 	      improperly display messages sent with other content-codings.  The
- * 	      server might also make this decision based on information about
- * 	      the particular user-agent or client.
- * 	      Note: Most HTTP/1.0 applications do not recognize or obey qvalues
- * 	      associated with content-codings. This means that qvalues will not
- * 	      work and are not permitted with x-gzip or x-compress.
+ * <p class='bcode'>
+ * 	Accept-Encoding  = "Accept-Encoding" ":"
+ * 	                   1#( codings [ ";" "q" "=" qvalue ] )
+ * 	codings          = ( content-coding | "*" )
  * </p>
+ * <p>
+ * Examples of its use are:
+ * <p class='bcode'>
+ * 	Accept-Encoding: compress, gzip
+ * 	Accept-Encoding:
+ * 	Accept-Encoding: *
+ * 	Accept-Encoding: compress;q=0.5, gzip;q=1.0
+ * 	Accept-Encoding: gzip;q=1.0, identity; q=0.5, *;q=0
+ * </p>
+ * <p>
+ * A server tests whether a content-coding is acceptable, according to an Accept-Encoding field, using these rules:
+ * <ol>
+ * 	<li>If the content-coding is one of the content-codings listed in the Accept-Encoding field, then it is
+ * 		acceptable, unless it is accompanied by a qvalue of 0.
+ * 		(As defined in section 3.9, a qvalue of 0 means "not acceptable.")
+ * 	<li>The special "*" symbol in an Accept-Encoding field matches any available content-coding not explicitly listed
+ * 		in the header field.
+ * 	<li>If multiple content-codings are acceptable, then the acceptable content-coding with the highest non-zero
+ * 		qvalue is preferred.
+ * 	<li>The "identity" content-coding is always acceptable, unless specifically refused because the Accept-Encoding
+ * 		field includes "identity;q=0", or because the field includes "*;q=0" and does not explicitly include the
+ * 		"identity" content-coding.
+ * 		If the Accept-Encoding field-value is empty, then only the "identity" encoding is acceptable.
+ * </ol>
+ * <p>
+ * If an Accept-Encoding field is present in a request, and if the server cannot send a response which is acceptable
+ * according to the Accept-Encoding header, then the server SHOULD send an error response with the 406 (Not Acceptable)
+ * status code.
+ * <p>
+ * If no Accept-Encoding field is present in a request, the server MAY assume that the client will accept any content
+ * coding.
+ * In this case, if "identity" is one of the available content-codings, then the server SHOULD use the "identity"
+ * content-coding, unless it has additional information that a different content-coding is meaningful to the client.
+ * <p>
+ * Note: If the request does not include an Accept-Encoding field, and if the "identity" content-coding is unavailable,
+ * then content-codings commonly understood by HTTP/1.0 clients (i.e.,"gzip" and "compress") are preferred; some older
+ * clients improperly display messages sent with other content-codings.
+ * The server might also make this decision based on information about the particular user-agent or client.
+ * <p>
+ * Note: Most HTTP/1.0 applications do not recognize or obey qvalues associated with content-codings.
+ * This means that qvalues will not work and are not permitted with x-gzip or x-compress.
  */
-public final class AcceptEncoding {
-
-	private static final boolean nocache = Boolean.getBoolean("juneau.http.AcceptEncoding.nocache");
-	private static final ConcurrentHashMap<String,AcceptEncoding> cache = new ConcurrentHashMap<String,AcceptEncoding>();
+public final class AcceptEncoding extends HeaderRangeArray {
 
-	private final TypeRange[] typeRanges;
-	private final List<TypeRange> typeRangesList;
+	private static final Cache<String,AcceptEncoding> cache = new Cache<String,AcceptEncoding>(NOCACHE, CACHE_MAX_SIZE);
 
 	/**
 	 * Returns a parsed <code>Accept-Encoding</code> header.
 	 *
-	 * @param s The <code>Accept-Encoding</code> header string.
+	 * @param value The <code>Accept-Encoding</code> header string.
 	 * @return The parsed <code>Accept-Encoding</code> header, or <jk>null</jk> if the string was null.
 	 */
-	public static AcceptEncoding forString(String s) {
-		if (s == null)
+	public static AcceptEncoding forString(String value) {
+		if (value == null)
 			return null;
-
-		// Prevent OOM in case of DDOS
-		if (cache.size() > 1000)
-			cache.clear();
-
-		while (true) {
-			AcceptEncoding a = cache.get(s);
-			if (a != null)
-				return a;
-			a = new AcceptEncoding(s);
-			if (nocache)
-				return a;
-			cache.putIfAbsent(s, a);
-		}
-	}
-
-	private AcceptEncoding(String raw) {
-		this.typeRanges = TypeRange.parse(raw);
-		this.typeRangesList = Collections.unmodifiableList(Arrays.asList(typeRanges));
-	}
-
-	/**
-	 * Returns the list of the types ranges that make up this header.
-	 * <p>
-	 * The types ranges in the list are sorted by their q-value in descending order.
-	 *
-	 * @return An unmodifiable list of type ranges.
-	 */
-	public List<TypeRange> getTypeRanges() {
-		return typeRangesList;
-	}
-
-	/**
-	 * Given a list of content codings, returns the best match for this <code>Accept-Encoding</code> header.
-	 * <p>
-	 *
-	 * @param contentCodings The codings to match against.
-	 * @return The index into the array of the best match, or <code>-1</code> if no suitable matches could be found.
-	 */
-	public int findMatch(String[] contentCodings) {
-
-		// Type ranges are ordered by 'q'.
-		// So we only need to search until we've found a match.
-		for (TypeRange mr : typeRanges)
-			for (int i = 0; i < contentCodings.length; i++)
-				if (mr.matches(contentCodings[i]))
-					return i;
-
-		return -1;
+		AcceptEncoding a = cache.get(value);
+		if (a == null)
+			a = cache.put(value, new AcceptEncoding(value));
+		return a;
 	}
 
-	@Override /* Object */
-	public String toString() {
-		return StringUtils.join(typeRanges, ',');
+	private AcceptEncoding(String value) {
+		super(value);
 	}
 }

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/fa4736b6/juneau-core/src/main/java/org/apache/juneau/http/AcceptLanguage.java
----------------------------------------------------------------------
diff --git a/juneau-core/src/main/java/org/apache/juneau/http/AcceptLanguage.java b/juneau-core/src/main/java/org/apache/juneau/http/AcceptLanguage.java
new file mode 100644
index 0000000..654abf7
--- /dev/null
+++ b/juneau-core/src/main/java/org/apache/juneau/http/AcceptLanguage.java
@@ -0,0 +1,110 @@
+// ***************************************************************************************************************************
+// * Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements.  See the NOTICE file *
+// * distributed with this work for additional information regarding copyright ownership.  The ASF licenses this file        *
+// * to you under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance            *
+// * with the License.  You may obtain a copy of the License at                                                              *
+// *                                                                                                                         *
+// *  http://www.apache.org/licenses/LICENSE-2.0                                                                             *
+// *                                                                                                                         *
+// * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an  *
+// * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the License for the        *
+// * specific language governing permissions and limitations under the License.                                              *
+// ***************************************************************************************************************************
+package org.apache.juneau.http;
+
+import static org.apache.juneau.http.Constants.*;
+
+import org.apache.juneau.internal.*;
+
+/**
+ * Represents a parsed <l>Accept-Language</l> HTTP request header.
+ * <p>
+ * List of acceptable human languages for response.
+ *
+ * <h6 class='figure'>Example</h6>
+ * <p class='bcode'>
+ * 	Accept-Language: en-US
+ * </p>
+ *
+ * <h6 class='topic'>RFC2616 Specification</h6>
+ *
+ * The Accept-Language request-header field is similar to Accept, but restricts the set of natural languages that are
+ * preferred as a response to the request.
+ * Language tags are defined in section 3.10.
+ *
+ * <p class='bcode'>
+ * 	Accept-Language = "Accept-Language" ":"
+ * 	                  1#( language-range [ ";" "q" "=" qvalue ] )
+ * 	language-range  = ( ( 1*8ALPHA *( "-" 1*8ALPHA ) ) | "*" )
+ * </p>
+ * <p>
+ * Each language-range MAY be given an associated quality value which represents an estimate of the user's preference
+ * for the languages specified by that range.
+ * The quality value defaults to "q=1".
+ * For example...
+ * <p class='bcode'>
+ * 	Accept-Language: da, en-gb;q=0.8, en;q=0.7
+ * </p>
+ * <p>
+ * ...would mean: "I prefer Danish, but will accept British English and other types of English."
+ * <p>
+ * A language-range matches a language-tag if it exactly equals the tag, or if it exactly equals a prefix of the tag
+ * such that the first tag character following the prefix is "-".
+ * <p>
+ * The special range "*", if present in the Accept-Language field, matches every tag not matched by any other range
+ * present in the Accept-Language field.
+ * <p>
+ * Note: This use of a prefix matching rule does not imply that language tags are assigned to languages in such a way
+ * that it is always true that if a user understands a language with a certain
+ * tag, then this user will also understand all languages with tags for which this tag is a prefix.
+ * The prefix rule simply allows the use of prefix tags if this is the case.
+ * <p>
+ * The language quality factor assigned to a language-tag by the Accept-Language field is the quality value of the
+ * longest language- range in the field that matches the language-tag.
+ * <p>
+ * If no language- range in the field matches the tag, the language quality factor assigned is 0.
+ * <p>
+ * If no Accept-Language header is present in the request, the server SHOULD assume that all languages are equally
+ * acceptable.
+ * <p>
+ * If an Accept-Language header is present, then all languages which are assigned a quality factor greater than 0 are
+ * acceptable.
+ * <p>
+ * It might be contrary to the privacy expectations of the user to send an Accept-Language header with the complete
+ * linguistic preferences of the user in every request.
+ * For a discussion of this issue, see section 15.1.4.
+ * <p>
+ * As intelligibility is highly dependent on the individual user, it is recommended that client applications make the
+ * choice of linguistic preference available to the user.
+ * If the choice is not made available, then the Accept-Language header field MUST NOT be given in the request.
+ * <p>
+ * Note: When making the choice of linguistic preference available to the user, we remind implementors of the fact that
+ * users are not familiar with the details of language matching as described above, and should provide appropriate
+ * guidance.
+ * As an example, users might assume that on selecting "en-gb", they will be served any kind of English document if
+ * British English is not available.
+ * A user agent might suggest in such a case to add "en" to get the best matching behavior.
+ */
+public final class AcceptLanguage extends HeaderRangeArray {
+
+	private static final Cache<String,AcceptLanguage> cache = new Cache<String,AcceptLanguage>(NOCACHE, CACHE_MAX_SIZE);
+
+	/**
+	 * Returns a parsed <code>Accept-Language</code> header.
+	 *
+	 * @param value The <code>Accept-Language</code> header string.
+	 * @return The parsed <code>Accept-Language</code> header, or <jk>null</jk> if the string was null.
+	 */
+	public static AcceptLanguage forString(String value) {
+		if (value == null)
+			return null;
+		AcceptLanguage a = cache.get(value);
+		if (a == null)
+			a = cache.put(value, new AcceptLanguage(value));
+		return a;
+	}
+
+	private AcceptLanguage(String raw) {
+		super(raw);
+	}
+}

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/fa4736b6/juneau-core/src/main/java/org/apache/juneau/http/AcceptRanges.java
----------------------------------------------------------------------
diff --git a/juneau-core/src/main/java/org/apache/juneau/http/AcceptRanges.java b/juneau-core/src/main/java/org/apache/juneau/http/AcceptRanges.java
new file mode 100644
index 0000000..eeb4aea
--- /dev/null
+++ b/juneau-core/src/main/java/org/apache/juneau/http/AcceptRanges.java
@@ -0,0 +1,69 @@
+// ***************************************************************************************************************************
+// * Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements.  See the NOTICE file *
+// * distributed with this work for additional information regarding copyright ownership.  The ASF licenses this file        *
+// * to you under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance            *
+// * with the License.  You may obtain a copy of the License at                                                              *
+// *                                                                                                                         *
+// *  http://www.apache.org/licenses/LICENSE-2.0                                                                             *
+// *                                                                                                                         *
+// * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an  *
+// * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the License for the        *
+// * specific language governing permissions and limitations under the License.                                              *
+// ***************************************************************************************************************************
+package org.apache.juneau.http;
+
+/**
+ * Represents a parsed <l>Accept-Range</l> HTTP response header.
+ * <p>
+ * What partial content range types this server supports via byte serving.
+ *
+ * <h6 class='figure'>Example</h6>
+ * <p class='bcode'>
+ * 	Accept-Ranges: bytes
+ * </p>
+ *
+ * <h6 class='topic'>RFC2616 Specification</h6>
+ *
+ * The Accept-Ranges response-header field allows the server to indicate its acceptance of range requests for a
+ * resource:
+ * <p class='bcode'>
+ * 	Accept-Ranges     = "Accept-Ranges" ":" acceptable-ranges
+ * 	acceptable-ranges = 1#range-unit | "none"
+ * </p>
+ * <p>
+ * Origin servers that accept byte-range requests MAY send...
+ * <p class='bcode'>
+ * 	Accept-Ranges: bytes
+ * </p>
+ * <p>
+ * ...but are not required to do so.
+ * <p>
+ * Clients MAY generate byte-range requests without having received this header for the resource involved.
+ * <p>
+ * Range units are defined in section 3.12.
+ * <p>
+ * Servers that do not accept any kind of range request for a resource MAY send...
+ * <p class='bcode'>
+ * 	Accept-Ranges: none
+ * </p>
+ * <p>
+ * ...to advise the client not to attempt a range request.
+ */
+public final class AcceptRanges extends HeaderString {
+
+	/**
+	 * Returns a parsed <code>Accept-Ranges</code> header.
+	 *
+	 * @param value The <code>Accept-Ranges</code> header string.
+	 * @return The parsed <code>Accept-Ranges</code> header, or <jk>null</jk> if the string was null.
+	 */
+	public static AcceptRanges forString(String value) {
+		if (value == null)
+			return null;
+		return new AcceptRanges(value);
+	}
+
+	private AcceptRanges(String value) {
+		super(value);
+	}
+}

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/fa4736b6/juneau-core/src/main/java/org/apache/juneau/http/Age.java
----------------------------------------------------------------------
diff --git a/juneau-core/src/main/java/org/apache/juneau/http/Age.java b/juneau-core/src/main/java/org/apache/juneau/http/Age.java
new file mode 100644
index 0000000..1e4aec5
--- /dev/null
+++ b/juneau-core/src/main/java/org/apache/juneau/http/Age.java
@@ -0,0 +1,64 @@
+// ***************************************************************************************************************************
+// * Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements.  See the NOTICE file *
+// * distributed with this work for additional information regarding copyright ownership.  The ASF licenses this file        *
+// * to you under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance            *
+// * with the License.  You may obtain a copy of the License at                                                              *
+// *                                                                                                                         *
+// *  http://www.apache.org/licenses/LICENSE-2.0                                                                             *
+// *                                                                                                                         *
+// * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an  *
+// * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the License for the        *
+// * specific language governing permissions and limitations under the License.                                              *
+// ***************************************************************************************************************************
+package org.apache.juneau.http;
+
+/**
+ * Represents a parsed <l>Age</l> HTTP response header.
+ * <p>
+ * The age the object has been in a proxy cache in seconds.
+ *
+ * <h6 class='figure'>Example</h6>
+ * <p class='bcode'>
+ * 	Age: 12
+ * </p>
+ *
+ * <h6 class='topic'>RFC2616 Specification</h6>
+ *
+ * The Age response-header field conveys the sender's estimate of the amount of time since the response (or its
+ * revalidation) was generated at the origin server.
+ * A cached response is "fresh" if its age does not exceed its freshness lifetime.
+ * Age values are calculated as specified in section 13.2.3.
+ *
+ * <p class='bcode'>
+ * 	Age = "Age" ":" age-value
+ * 	age-value = delta-seconds
+ * </p>
+ * <p>
+ * Age values are non-negative decimal integers, representing time in seconds.
+ * <p>
+ * If a cache receives a value larger than the largest positive integer it can represent, or if any of its age
+ * calculations overflows, it MUST transmit an Age header with a value of 2147483648 (2^31).
+ * <p>
+ * An HTTP/1.1 server that includes a cache MUST include an Age header field in every response generated from its own
+ * cache.
+ * <p>
+ * Caches SHOULD use an arithmetic type of at least 31 bits of range.
+ */
+public final class Age extends HeaderInteger {
+
+	/**
+	 * Returns a parsed <code>Age</code> header.
+	 *
+	 * @param value The <code>Age</code> header string.
+	 * @return The parsed <code>Age</code> header, or <jk>null</jk> if the string was null.
+	 */
+	public static Age forString(String value) {
+		if (value == null)
+			return null;
+		return new Age(value);
+	}
+
+	private Age(String value) {
+		super(value);
+	}
+}

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/fa4736b6/juneau-core/src/main/java/org/apache/juneau/http/Allow.java
----------------------------------------------------------------------
diff --git a/juneau-core/src/main/java/org/apache/juneau/http/Allow.java b/juneau-core/src/main/java/org/apache/juneau/http/Allow.java
new file mode 100644
index 0000000..67dbc80
--- /dev/null
+++ b/juneau-core/src/main/java/org/apache/juneau/http/Allow.java
@@ -0,0 +1,72 @@
+// ***************************************************************************************************************************
+// * Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements.  See the NOTICE file *
+// * distributed with this work for additional information regarding copyright ownership.  The ASF licenses this file        *
+// * to you under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance            *
+// * with the License.  You may obtain a copy of the License at                                                              *
+// *                                                                                                                         *
+// *  http://www.apache.org/licenses/LICENSE-2.0                                                                             *
+// *                                                                                                                         *
+// * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an  *
+// * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the License for the        *
+// * specific language governing permissions and limitations under the License.                                              *
+// ***************************************************************************************************************************
+package org.apache.juneau.http;
+
+/**
+ * Represents a parsed <l>Allow</l> HTTP response header.
+ * <p>
+ * Valid methods for a specified resource. To be used for a 405 Method not allowed.
+ *
+ * <h6 class='figure'>Example</h6>
+ * <p class='bcode'>
+ * 	Allow: GET, HEAD
+ * </p>
+ *
+ * <h6 class='topic'>RFC2616 Specification</h6>
+ *
+ * The Allow entity-header field lists the set of methods supported by the resource identified by the Request-URI.
+ * The purpose of this field is strictly to inform the recipient of valid methods associated with the resource.
+ * An Allow header field MUST be present in a 405 (Method Not Allowed) response.
+ *
+ * <p class='bcode'>
+ * 	Allow   = "Allow" ":" #Method
+ * </p>
+ * <p>
+ * Example of use:
+ * <p class='bcode'>
+ * 	Allow: GET, HEAD, PUT
+ * </p>
+ * <p>
+ * This field cannot prevent a client from trying other methods.
+ * However, the indications given by the Allow header field value SHOULD be followed.
+ * <p>
+ * The actual set of allowed methods is defined by the origin server at the time of each request.
+ * <p>
+ * The Allow header field MAY be provided with a PUT request to recommend the methods to be supported by the new or
+ * modified resource.
+ * <p>
+ * The server is not required to support these methods and SHOULD include an Allow header in the response giving the
+ * actual supported methods.
+ * <p>
+ * A proxy MUST NOT modify the Allow header field even if it does not understand all the methods specified, since the
+ * user agent might
+ * have other means of communicating with the origin server.
+ */
+public final class Allow extends HeaderStringArray {
+
+	/**
+	 * Returns a parsed <code>Allow</code> header.
+	 *
+	 * @param value The <code>Allow</code> header string.
+	 * @return The parsed <code>Allow</code> header, or <jk>null</jk> if the string was null.
+	 */
+	public static Allow forString(String value) {
+		if (value == null)
+			return null;
+		return new Allow(value);
+	}
+
+	private Allow(String value) {
+		super(value);
+	}
+}

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/fa4736b6/juneau-core/src/main/java/org/apache/juneau/http/Authorization.java
----------------------------------------------------------------------
diff --git a/juneau-core/src/main/java/org/apache/juneau/http/Authorization.java b/juneau-core/src/main/java/org/apache/juneau/http/Authorization.java
new file mode 100644
index 0000000..530bd4d
--- /dev/null
+++ b/juneau-core/src/main/java/org/apache/juneau/http/Authorization.java
@@ -0,0 +1,78 @@
+// ***************************************************************************************************************************
+// * Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements.  See the NOTICE file *
+// * distributed with this work for additional information regarding copyright ownership.  The ASF licenses this file        *
+// * to you under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance            *
+// * with the License.  You may obtain a copy of the License at                                                              *
+// *                                                                                                                         *
+// *  http://www.apache.org/licenses/LICENSE-2.0                                                                             *
+// *                                                                                                                         *
+// * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an  *
+// * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the License for the        *
+// * specific language governing permissions and limitations under the License.                                              *
+// ***************************************************************************************************************************
+package org.apache.juneau.http;
+
+/**
+ * Represents a parsed <l>Authorization</l> HTTP request header.
+ * <p>
+ * Authentication credentials for HTTP authentication.
+ *
+ * <h6 class='figure'>Example</h6>
+ * <p class='bcode'>
+ * 	Authorization: Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ==
+ * </p>
+ *
+ * <h6 class='topic'>RFC2616 Specification</h6>
+ *
+ * A user agent that wishes to authenticate itself with a server--usually, but not necessarily, after receiving a 401
+ * response--does so by including an Authorization request-header field with the request.
+ * <p>
+ * The Authorization field value consists of credentials containing the authentication information of the user agent for
+ * the realm of the resource being requested.
+ *
+ * <p class='bcode'>
+ * 	Authorization  = "Authorization" ":" credentials
+ * </p>
+ * <p>
+ * HTTP access authentication is described in "HTTP Authentication: Basic and Digest Access Authentication".
+ * <p>
+ * If a request is authenticated and a realm specified, the same credentials SHOULD be valid for all other requests
+ * within this realm (assuming that the authentication scheme itself does not require otherwise, such as credentials
+ * that vary according to a challenge value or using synchronized clocks).
+ * <p>
+ * When a shared cache (see section 13.7) receives a request containing an Authorization field, it MUST NOT return the
+ * corresponding response as a reply to any other request, unless one of the following specific exceptions holds:
+ * <ol>
+ * 	<li>If the response includes the "s-maxage" cache-control directive, the cache MAY use that response in replying
+ * 		to a subsequent request.
+ * 		But (if the specified maximum age has passed) a proxy cache MUST first revalidate it with the origin
+ * 		server, using the request-headers from the new request to allow the origin server to authenticate the new
+ * 		request.
+ * 		(This is the defined behavior for s-maxage.)
+ * 		If the response includes "s-maxage=0", the proxy MUST always revalidate it before re-using it.
+ * 	<li>If the response includes the "must-revalidate" cache-control directive, the cache MAY use that response in
+ * 		replying to a subsequent request.
+ * 		But if the response is stale, all caches MUST first revalidate it with the origin server, using the
+ * 		request-headers from the new request to allow the origin server to authenticate the new request.
+ * 	<li>If the response includes the "public" cache-control directive, it MAY be returned in reply to any subsequent
+ * 		request.
+ * </ol>
+ */
+public final class Authorization extends HeaderString {
+
+	/**
+	 * Returns a parsed <code>Authorization</code> header.
+	 *
+	 * @param value The <code>Authorization</code> header string.
+	 * @return The parsed <code>Authorization</code> header, or <jk>null</jk> if the string was null.
+	 */
+	public static Authorization forString(String value) {
+		if (value == null)
+			return null;
+		return new Authorization(value);
+	}
+
+	private Authorization(String value) {
+		super(value);
+	}
+}

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/fa4736b6/juneau-core/src/main/java/org/apache/juneau/http/CacheControl.java
----------------------------------------------------------------------
diff --git a/juneau-core/src/main/java/org/apache/juneau/http/CacheControl.java b/juneau-core/src/main/java/org/apache/juneau/http/CacheControl.java
new file mode 100644
index 0000000..27a67a2
--- /dev/null
+++ b/juneau-core/src/main/java/org/apache/juneau/http/CacheControl.java
@@ -0,0 +1,102 @@
+// ***************************************************************************************************************************
+// * Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements.  See the NOTICE file *
+// * distributed with this work for additional information regarding copyright ownership.  The ASF licenses this file        *
+// * to you under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance            *
+// * with the License.  You may obtain a copy of the License at                                                              *
+// *                                                                                                                         *
+// *  http://www.apache.org/licenses/LICENSE-2.0                                                                             *
+// *                                                                                                                         *
+// * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an  *
+// * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the License for the        *
+// * specific language governing permissions and limitations under the License.                                              *
+// ***************************************************************************************************************************
+package org.apache.juneau.http;
+
+/**
+ * Represents a parsed <l>Cache-Control</l> HTTP request header.
+ * <p>
+ * Used to specify directives that must be obeyed by all caching mechanisms along the request-response chain.
+ *
+ * <h6 class='figure'>Example</h6>
+ * <p class='bcode'>
+ * 	Cache-Control: no-cache
+ * </p>
+ *
+ * <h6 class='topic'>RFC2616 Specification</h6>
+ *
+ * The Cache-Control general-header field is used to specify directives that MUST be obeyed by all caching mechanisms
+ * along the request/response chain.
+ * The directives specify behavior intended to prevent caches from adversely interfering with the request or response.
+ * These directives typically override the default caching algorithms.
+ * Cache directives are unidirectional in that the presence of a directive in a request does not imply that the same
+ * directive is to be given in the response.
+ * <p>
+ * Note that HTTP/1.0 caches might not implement Cache-Control and might only implement Pragma: no-cache (see section
+ * 14.32).
+ * <p>
+ * Cache directives MUST be passed through by a proxy or gateway application, regardless of their significance to that
+ * application, since the directives might be applicable to all recipients along the request/response chain.
+ * It is not possible to specify a cache- directive for a specific cache.
+ *
+ * <p class='bcode'>
+ * 	Cache-Control   = "Cache-Control" ":" 1#cache-directive
+ * 	cache-directive = cache-request-directive
+ * 	     | cache-response-directive
+ * 	cache-request-directive =
+ * 	       "no-cache"                          ; Section 14.9.1
+ * 	     | "no-store"                          ; Section 14.9.2
+ * 	     | "max-age" "=" delta-seconds         ; Section 14.9.3, 14.9.4
+ * 	     | "max-stale" [ "=" delta-seconds ]   ; Section 14.9.3
+ * 	     | "min-fresh" "=" delta-seconds       ; Section 14.9.3
+ * 	     | "no-transform"                      ; Section 14.9.5
+ * 	     | "only-if-cached"                    ; Section 14.9.4
+ * 	     | cache-extension                     ; Section 14.9.6
+ * 	cache-response-directive =
+ * 	       "public"                               ; Section 14.9.1
+ * 	     | "private" [ "=" <"> 1#field-name <"> ] ; Section 14.9.1
+ * 	     | "no-cache" [ "=" <"> 1#field-name <"> ]; Section 14.9.1
+ * 	     | "no-store"                             ; Section 14.9.2
+ * 	     | "no-transform"                         ; Section 14.9.5
+ * 	     | "must-revalidate"                      ; Section 14.9.4
+ * 	     | "proxy-revalidate"                     ; Section 14.9.4
+ * 	     | "max-age" "=" delta-seconds            ; Section 14.9.3
+ * 	     | "s-maxage" "=" delta-seconds           ; Section 14.9.3
+ * 	     | cache-extension                        ; Section 14.9.6
+ * 	cache-extension = token [ "=" ( token | quoted-string ) ]
+ * </p>
+ * <p>
+ * When a directive appears without any 1#field-name parameter, the directive applies to the entire request or response.
+ * When such a directive appears with a 1#field-name parameter, it applies only to the named field or fields, and not
+ * to the rest of the request or response. This mechanism supports extensibility; implementations of future versions
+ * of the HTTP protocol might apply these directives to header fields not defined in HTTP/1.1.
+ * <p>
+ * The cache-control directives can be broken down into these general categories:
+ * <ul>
+ * 	<li>Restrictions on what are cacheable; these may only be imposed by the origin server.
+ * 	<li>Restrictions on what may be stored by a cache; these may be imposed by either the origin server or the user
+ * 		agent.
+ * 	<li>Modifications of the basic expiration mechanism; these may be imposed by either the origin server or the
+ * 		user agent.
+ * 	<li>Controls over cache revalidation and reload; these may only be imposed by a user agent.
+ * 	<li>Control over transformation of entities.
+ * 	<li>Extensions to the caching system.
+ * </ul>
+ */
+public final class CacheControl extends HeaderString {
+
+	/**
+	 * Returns a parsed <code>Cache-Control</code> header.
+	 *
+	 * @param value The <code>Cache-Control</code> header string.
+	 * @return The parsed <code>Cache-Control</code> header, or <jk>null</jk> if the string was null.
+	 */
+	public static CacheControl forString(String value) {
+		if (value == null)
+			return null;
+		return new CacheControl(value);
+	}
+
+	private CacheControl(String value) {
+		super(value);
+	}
+}

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/fa4736b6/juneau-core/src/main/java/org/apache/juneau/http/Connection.java
----------------------------------------------------------------------
diff --git a/juneau-core/src/main/java/org/apache/juneau/http/Connection.java b/juneau-core/src/main/java/org/apache/juneau/http/Connection.java
new file mode 100644
index 0000000..2eaec3a
--- /dev/null
+++ b/juneau-core/src/main/java/org/apache/juneau/http/Connection.java
@@ -0,0 +1,106 @@
+// ***************************************************************************************************************************
+// * Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements.  See the NOTICE file *
+// * distributed with this work for additional information regarding copyright ownership.  The ASF licenses this file        *
+// * to you under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance            *
+// * with the License.  You may obtain a copy of the License at                                                              *
+// *                                                                                                                         *
+// *  http://www.apache.org/licenses/LICENSE-2.0                                                                             *
+// *                                                                                                                         *
+// * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an  *
+// * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the License for the        *
+// * specific language governing permissions and limitations under the License.                                              *
+// ***************************************************************************************************************************
+package org.apache.juneau.http;
+
+/**
+ * Represents a parsed <l>Connection</l> HTTP request header.
+ * <p>
+ * Control options for the current connection and list of hop-by-hop request fields.
+ *
+ * <h6 class='figure'>Example</h6>
+ * <p class='bcode'>
+ * 	Connection: keep-alive
+ * 	Connection: Upgrade
+ * </p>
+ *
+ * <h6 class='topic'>RFC2616 Specification</h6>
+ *
+ * The Connection general-header field allows the sender to specify options that are desired for that particular
+ * connection and MUST NOT be communicated by proxies over further connections.
+ * <p>
+ * The Connection header has the following grammar:
+ * <p class='bcode'>
+ * 	Connection = "Connection" ":" 1#(connection-token)
+ * 	connection-token  = token
+ * </p>
+ * <p>
+ * HTTP/1.1 proxies MUST parse the Connection header field before a message is forwarded and, for each connection-token
+ * in this field, remove any header field(s) from the message with the same name as the connection-token.
+ * Connection options are signaled by the presence of a connection-token in the Connection header field, not by any
+ * corresponding additional header field(s), since the additional header field may not be sent if there are no
+ * parameters associated with that connection option.
+ * <p>
+ * Message headers listed in the Connection header MUST NOT include end-to-end headers, such as Cache-Control.
+ * <p>
+ * HTTP/1.1 defines the "close" connection option for the sender to signal that the connection will be closed after
+ * completion of the response.
+ * For example...
+ * <p class='bcode'>
+ * 	Connection: close
+ * </p>
+ * <p>
+ * ...in either the request or the response header fields indicates that the connection SHOULD NOT be considered
+ * `persistent' (section 8.1) after the current request/response is complete.
+ * <p>
+ * HTTP/1.1 applications that do not support persistent connections MUST include the "close" connection option in
+ * every message.
+ * <p>
+ * A system receiving an HTTP/1.0 (or lower-version) message that includes a Connection header MUST, for each
+ * connection-token in this field, remove and ignore any header field(s) from the message with the same name as the
+ * connection-token.
+ * This protects against mistaken forwarding of such header fields by pre-HTTP/1.1 proxies.
+ * See section 19.6.2.
+ */
+public final class Connection extends HeaderString {
+
+	/**
+	 * Returns a parsed <code>Connection</code> header.
+	 *
+	 * @param value The <code>Connection</code> header string.
+	 * @return The parsed <code>Connection</code> header, or <jk>null</jk> if the string was null.
+	 */
+	public static Connection forString(String value) {
+		if (value == null)
+			return null;
+		return new Connection(value);
+	}
+
+
+	private Connection(String value) {
+		super(value);
+	}
+
+	/**
+	 * Returns <jk>true</jk> if the header value is <code>close</code>.
+	 * @return <jk>true</jk> if the header value is <code>close</code>.
+	 */
+	public boolean isClose() {
+		return eqIC("close");
+	}
+
+	/**
+	 * Returns <jk>true</jk> if the header value is <code>keep-alive</code>.
+	 * @return <jk>true</jk> if the header value is <code>keep-alive</code>.
+	 */
+	public boolean isKeepAlive() {
+		return eqIC("keep-alive");
+	}
+
+	/**
+	 * Returns <jk>true</jk> if the header value is <code>upgrade</code>.
+	 * @return <jk>true</jk> if the header value is <code>upgrade</code>.
+	 */
+	public boolean isUpgrade() {
+		return eqIC("upgrade");
+	}
+}

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/fa4736b6/juneau-core/src/main/java/org/apache/juneau/http/Constants.java
----------------------------------------------------------------------
diff --git a/juneau-core/src/main/java/org/apache/juneau/http/Constants.java b/juneau-core/src/main/java/org/apache/juneau/http/Constants.java
new file mode 100644
index 0000000..7f31635
--- /dev/null
+++ b/juneau-core/src/main/java/org/apache/juneau/http/Constants.java
@@ -0,0 +1,21 @@
+// ***************************************************************************************************************************
+// * Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements.  See the NOTICE file *
+// * distributed with this work for additional information regarding copyright ownership.  The ASF licenses this file        *
+// * to you under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance            *
+// * with the License.  You may obtain a copy of the License at                                                              *
+// *                                                                                                                         *
+// *  http://www.apache.org/licenses/LICENSE-2.0                                                                             *
+// *                                                                                                                         *
+// * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an  *
+// * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the License for the        *
+// * specific language governing permissions and limitations under the License.                                              *
+// ***************************************************************************************************************************
+package org.apache.juneau.http;
+
+/**
+ * Constants used by classes in this package.
+ */
+public class Constants {
+	static boolean NOCACHE = Boolean.getBoolean("juneau.http.cache.disable");
+	static int CACHE_MAX_SIZE = Integer.getInteger("juneau.http.cache.maxSize", 1000);
+}

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/fa4736b6/juneau-core/src/main/java/org/apache/juneau/http/ContentEncoding.java
----------------------------------------------------------------------
diff --git a/juneau-core/src/main/java/org/apache/juneau/http/ContentEncoding.java b/juneau-core/src/main/java/org/apache/juneau/http/ContentEncoding.java
new file mode 100644
index 0000000..bb92921
--- /dev/null
+++ b/juneau-core/src/main/java/org/apache/juneau/http/ContentEncoding.java
@@ -0,0 +1,74 @@
+// ***************************************************************************************************************************
+// * Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements.  See the NOTICE file *
+// * distributed with this work for additional information regarding copyright ownership.  The ASF licenses this file        *
+// * to you under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance            *
+// * with the License.  You may obtain a copy of the License at                                                              *
+// *                                                                                                                         *
+// *  http://www.apache.org/licenses/LICENSE-2.0                                                                             *
+// *                                                                                                                         *
+// * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an  *
+// * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the License for the        *
+// * specific language governing permissions and limitations under the License.                                              *
+// ***************************************************************************************************************************
+package org.apache.juneau.http;
+
+/**
+ * Represents a parsed <l>Content-Encoding</l> HTTP response header.
+ * <p>
+ * The type of encoding used on the data.
+ *
+ * <h6 class='figure'>Example</h6>
+ * <p class='bcode'>
+ * 	Content-Encoding: gzip
+ * </p>
+ *
+ * <h6 class='topic'>RFC2616 Specification</h6>
+ *
+ * The Content-Encoding entity-header field is used as a modifier to the media-type.
+ * When present, its value indicates what additional content codings have been applied to the entity-body, and thus
+ * what decoding mechanisms must be applied in order to obtain the media-type referenced by the Content-Type header
+ * field.
+ * Content-Encoding is primarily used to allow a document to be compressed without losing the identity of its
+ * underlying media type.
+ * <p class='bcode'>
+ * 	Content-Encoding  = "Content-Encoding" ":" 1#content-coding
+ * </p>
+ * <p>
+ * Content codings are defined in section 3.5. An example of its use is...
+ * <p class='bcode'>
+ * 	Content-Encoding: gzip
+ * </p>
+ * <p>
+ * The content-coding is a characteristic of the entity identified by the Request-URI.
+ * Typically, the entity-body is stored with this encoding and is only decoded before rendering or analogous usage.
+ * However, a non-transparent proxy MAY modify the content-coding if the new coding is known to be acceptable to the
+ * recipient, unless the "no-transform" cache-control directive is present in the message.
+ * <p>
+ * If the content-coding of an entity is not "identity", then the response MUST include a Content-Encoding
+ * entity-header (section 14.11) that lists the non-identity content-coding(s) used.
+ * <p>
+ * If the content-coding of an entity in a request message is not acceptable to the origin server, the server SHOULD
+ * respond with a status code of 415 (Unsupported Media Type).
+ * <p>
+ * If multiple encodings have been applied to an entity, the content codings MUST be listed in the order in which they
+ * were applied.
+ * Additional information about the encoding parameters MAY be provided.
+ */
+public final class ContentEncoding extends HeaderEnum<ContentEncodingEnum> {
+
+	/**
+	 * Returns a parsed <code>Content-Encoding</code> header.
+	 *
+	 * @param value The <code>Content-Encoding</code> header string.
+	 * @return The parsed <code>Content-Encoding</code> header, or <jk>null</jk> if the string was null.
+	 */
+	public static ContentEncoding forString(String value) {
+		if (value == null)
+			return null;
+		return new ContentEncoding(value);
+	}
+
+	private ContentEncoding(String value) {
+		super(value, ContentEncodingEnum.class, ContentEncodingEnum.OTHER);
+	}
+}

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/fa4736b6/juneau-core/src/main/java/org/apache/juneau/http/ContentEncodingEnum.java
----------------------------------------------------------------------
diff --git a/juneau-core/src/main/java/org/apache/juneau/http/ContentEncodingEnum.java b/juneau-core/src/main/java/org/apache/juneau/http/ContentEncodingEnum.java
new file mode 100644
index 0000000..e44329a
--- /dev/null
+++ b/juneau-core/src/main/java/org/apache/juneau/http/ContentEncodingEnum.java
@@ -0,0 +1,34 @@
+// ***************************************************************************************************************************
+// * Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements.  See the NOTICE file *
+// * distributed with this work for additional information regarding copyright ownership.  The ASF licenses this file        *
+// * to you under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance            *
+// * with the License.  You may obtain a copy of the License at                                                              *
+// *                                                                                                                         *
+// *  http://www.apache.org/licenses/LICENSE-2.0                                                                             *
+// *                                                                                                                         *
+// * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an  *
+// * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the License for the        *
+// * specific language governing permissions and limitations under the License.                                              *
+// ***************************************************************************************************************************
+package org.apache.juneau.http;
+
+/**
+ * Represents the possible values for a <code>Content-Encoding</code> header.
+ */
+public enum ContentEncodingEnum {
+
+	/** Content-Encoding: gzip */
+	GZIP,
+
+	/** Content-Encoding: compress */
+	COMPRESS,
+
+	/** Content-Encoding: deflate */
+	DEFLATE,
+
+	/** Content-Encoding: identity */
+	IDENTITY,
+
+	/** Unknown value */
+	OTHER;
+}

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/fa4736b6/juneau-core/src/main/java/org/apache/juneau/http/ContentLanguage.java
----------------------------------------------------------------------
diff --git a/juneau-core/src/main/java/org/apache/juneau/http/ContentLanguage.java b/juneau-core/src/main/java/org/apache/juneau/http/ContentLanguage.java
new file mode 100644
index 0000000..bfebcbe
--- /dev/null
+++ b/juneau-core/src/main/java/org/apache/juneau/http/ContentLanguage.java
@@ -0,0 +1,78 @@
+// ***************************************************************************************************************************
+// * Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements.  See the NOTICE file *
+// * distributed with this work for additional information regarding copyright ownership.  The ASF licenses this file        *
+// * to you under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance            *
+// * with the License.  You may obtain a copy of the License at                                                              *
+// *                                                                                                                         *
+// *  http://www.apache.org/licenses/LICENSE-2.0                                                                             *
+// *                                                                                                                         *
+// * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an  *
+// * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the License for the        *
+// * specific language governing permissions and limitations under the License.                                              *
+// ***************************************************************************************************************************
+package org.apache.juneau.http;
+
+/**
+ * Represents a parsed <l>Content-Language</l> HTTP response header.
+ * <p>
+ * The natural language or languages of the intended audience for the enclosed content.
+ *
+ * <h6 class='figure'>Example</h6>
+ * <p class='bcode'>
+ * 	Content-Language: da
+ * </p>
+ *
+ * <h6 class='topic'>RFC2616 Specification</h6>
+ *
+ * The Content-Language entity-header field describes the natural language(s) of the intended audience for the
+ * enclosed entity.
+ * Note that this might not be equivalent to all the languages used within the entity-body.
+ * <p class='bcode'>
+ * 	Content-Language  = "Content-Language" ":" 1#language-tag
+ * </p>
+ * <p>
+ * Language tags are defined in section 3.10.
+ * The primary purpose of Content-Language is to allow a user to identify and differentiate entities according to the
+ * user's own preferred language.
+ * Thus, if the body content is intended only for a Danish-literate audience, the appropriate field is...
+ * <p class='bcode'>
+ * 	Content-Language: da
+ * </p>
+ * <p>
+ * If no Content-Language is specified, the default is that the content is intended for all language audiences.
+ * This might mean that the sender does not consider it to be specific to any natural language, or that the sender
+ * does not know for which language it is intended.
+ * <p>
+ * Multiple languages MAY be listed for content that is intended for multiple audiences.
+ * For example, a rendition of the "Treaty of Waitangi," presented simultaneously in the original Maori and English
+ * versions, would call for...
+ * <p class='bcode'>
+ * 	Content-Language: mi, en
+ * </p>
+ * <p>
+ * However, just because multiple languages are present within an entity does not mean that it is intended for
+ * multiple linguistic audiences.
+ * An example would be a beginner's language primer, such as "A First Lesson in Latin," which is clearly intended to
+ * be used by an English-literate audience.
+ * In this case, the Content-Language would properly only include "en".
+ * <p>
+ * Content-Language MAY be applied to any media type -- it is not limited to textual documents.
+ */
+public final class ContentLanguage extends HeaderStringArray {
+
+	/**
+	 * Returns a parsed <code>Content-Language</code> header.
+	 *
+	 * @param value The <code>Content-Language</code> header string.
+	 * @return The parsed <code>Content-Language</code> header, or <jk>null</jk> if the string was null.
+	 */
+	public static ContentLanguage forString(String value) {
+		if (value == null)
+			return null;
+		return new ContentLanguage(value);
+	}
+
+	private ContentLanguage(String value) {
+		super(value);
+	}
+}

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/fa4736b6/juneau-core/src/main/java/org/apache/juneau/http/ContentLength.java
----------------------------------------------------------------------
diff --git a/juneau-core/src/main/java/org/apache/juneau/http/ContentLength.java b/juneau-core/src/main/java/org/apache/juneau/http/ContentLength.java
new file mode 100644
index 0000000..9cb8959
--- /dev/null
+++ b/juneau-core/src/main/java/org/apache/juneau/http/ContentLength.java
@@ -0,0 +1,67 @@
+// ***************************************************************************************************************************
+// * Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements.  See the NOTICE file *
+// * distributed with this work for additional information regarding copyright ownership.  The ASF licenses this file        *
+// * to you under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance            *
+// * with the License.  You may obtain a copy of the License at                                                              *
+// *                                                                                                                         *
+// *  http://www.apache.org/licenses/LICENSE-2.0                                                                             *
+// *                                                                                                                         *
+// * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an  *
+// * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the License for the        *
+// * specific language governing permissions and limitations under the License.                                              *
+// ***************************************************************************************************************************
+package org.apache.juneau.http;
+
+/**
+ * Represents a parsed <l>Content-Length</l> HTTP request/response header.
+ * <p>
+ * The length of the response body in octets (8-bit bytes).
+ *
+ * <h6 class='figure'>Example</h6>
+ * <p class='bcode'>
+ * 	Content-Length: 348
+ * </p>
+ *
+ * <h6 class='topic'>RFC2616 Specification</h6>
+ *
+ * The Content-Length entity-header field indicates the size of the entity-body, in decimal number of OCTETs, sent to
+ * the recipient or, in the case of the HEAD method, the size of the entity-body that would have been sent had the
+ * request been a GET.
+ * <p class='bcode'>
+ * 	Content-Length    = "Content-Length" ":" 1*DIGIT
+ * </p>
+ * <p>
+ * An example is...
+ * <p class='bcode'>
+ * 	Content-Length: 3495
+ * </p>
+ * <p>
+ * Applications SHOULD use this field to indicate the transfer-length of the message-body, unless this is prohibited by
+ * the rules in section 4.4.
+ * <p>
+ * Any Content-Length greater than or equal to zero is a valid value.
+ * Section 4.4 describes how to determine the length of a message-body if a Content-Length is not given.
+ * <p>
+ * Note that the meaning of this field is significantly different from the corresponding definition in MIME, where it is
+ * an optional field used within the "message/external-body" content-type.
+ * In HTTP, it SHOULD be sent whenever the message's length can be determined prior to being transferred, unless this is
+ * prohibited by the rules in section 4.4.
+ */
+public final class ContentLength extends HeaderInteger {
+
+	/**
+	 * Returns a parsed <code>Content-Length</code> header.
+	 *
+	 * @param value The <code>Content-Length</code> header string.
+	 * @return The parsed <code>Content-Length</code> header, or <jk>null</jk> if the string was null.
+	 */
+	public static ContentLength forString(String value) {
+		if (value == null)
+			return null;
+		return new ContentLength(value);
+	}
+
+	private ContentLength(String value) {
+		super(value);
+	}
+}



[2/4] incubator-juneau git commit: Add HTTP header classes.

Posted by ja...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/fa4736b6/juneau-core/src/main/java/org/apache/juneau/http/IfNoneMatch.java
----------------------------------------------------------------------
diff --git a/juneau-core/src/main/java/org/apache/juneau/http/IfNoneMatch.java b/juneau-core/src/main/java/org/apache/juneau/http/IfNoneMatch.java
new file mode 100644
index 0000000..f587f07
--- /dev/null
+++ b/juneau-core/src/main/java/org/apache/juneau/http/IfNoneMatch.java
@@ -0,0 +1,95 @@
+// ***************************************************************************************************************************
+// * Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements.  See the NOTICE file *
+// * distributed with this work for additional information regarding copyright ownership.  The ASF licenses this file        *
+// * to you under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance            *
+// * with the License.  You may obtain a copy of the License at                                                              *
+// *                                                                                                                         *
+// *  http://www.apache.org/licenses/LICENSE-2.0                                                                             *
+// *                                                                                                                         *
+// * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an  *
+// * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the License for the        *
+// * specific language governing permissions and limitations under the License.                                              *
+// ***************************************************************************************************************************
+package org.apache.juneau.http;
+
+/**
+ * Represents a parsed <l>If-None-Match</l> HTTP request header.
+ * <p>
+ * Allows a 304 Not Modified to be returned if content is unchanged.
+ *
+ * <h6 class='figure'>Example</h6>
+ * <p class='bcode'>
+ * 	If-None-Match: "737060cd8c284d8af7ad3082f209582d"
+ * </p>
+ *
+ * <h6 class='topic'>RFC2616 Specification</h6>
+ *
+ * The If-None-Match request-header field is used with a method to make it conditional.
+ * A client that has one or more entities previously obtained from the resource can verify that none of those entities
+ * is current by including a list of their associated entity tags in the If-None-Match header field.
+ * The purpose of this feature is to allow efficient updates of cached information with a minimum amount of transaction
+ * overhead.
+ * It is also used to prevent a method (e.g. PUT) from inadvertently modifying an existing resource when the client
+ * believes that the resource does not exist.
+ * <p>
+ * As a special case, the value "*" matches any current entity of the resource.
+ * <p class='bcode'>
+ * 	If-None-Match = "If-None-Match" ":" ( "*" | 1#entity-tag )
+ * </p>
+ * <p>
+ * If any of the entity tags match the entity tag of the entity that would have been returned in the response to a
+ * similar GET request (without the If-None-Match header) on that resource, or if "*" is given
+ * and any current entity exists for that resource, then the server MUST NOT perform the requested method, unless
+ * required to do so because the resource's modification date fails to match that supplied in an If-Modified-Since
+ * header field in the request.
+ * Instead, if the request method was GET or HEAD, the server SHOULD respond with a 304 (Not Modified) response,
+ * including the cache- related header fields (particularly ETag) of one of the entities that matched.
+ * For all other request methods, the server MUST respond with a status of 412 (Precondition Failed).
+ * <p>
+ * See section 13.3.3 for rules on how to determine if two entities tags match.
+ * The weak comparison function can only be used with GET or HEAD requests.
+ * <p>
+ * If none of the entity tags match, then the server MAY perform the requested method as if the If-None-Match header
+ * field did not exist, but MUST also ignore any If-Modified-Since header field(s) in the request.
+ * That is, if no entity tags match, then the server MUST NOT return a 304 (Not Modified) response.
+ * <p>
+ * If the request would, without the If-None-Match header field, result in anything other than a 2xx or 304 status,
+ * then the If-None-Match header MUST be ignored.
+ * (See section 13.3.4 for a discussion of server behavior when both If-Modified-Since and If-None-Match appear in the
+ * same request.)
+ * <p>
+ * The meaning of "If-None-Match: *" is that the method MUST NOT be performed if the representation selected by the
+ * origin server (or by a cache, possibly using the Vary mechanism, see section 14.44) exists, and SHOULD be performed
+ * if the representation does not exist.
+ * This feature is intended to be useful in preventing races between PUT operations.
+ * <p>
+ * Examples:
+ * <p class='bcode'>
+ * 	If-None-Match: "xyzzy"
+ * 	If-None-Match: W/"xyzzy"
+ * 	If-None-Match: "xyzzy", "r2d2xxxx", "c3piozzzz"
+ * 	If-None-Match: W/"xyzzy", W/"r2d2xxxx", W/"c3piozzzz"
+ * 	If-None-Match: *
+ * </p>
+ * <p>
+ * The result of a request having both an If-None-Match header field and either an If-Match or an If-Unmodified-Since
+ * header fields is undefined by this specification.
+ */
+public final class IfNoneMatch extends HeaderEntityValidatorArray {
+
+	/**
+	 * Returns a parsed <code>If-None-Match</code> header.
+	 *
+	 * @param value The <code>If-None-Match</code> header string.
+	 * @return The parsed <code>If-None-Match</code> header, or <jk>null</jk> if the string was null.
+	 */
+	public static IfNoneMatch forString(String value) {
+		if (value == null)
+			return null;
+		return new IfNoneMatch(value);
+	}
+
+	private IfNoneMatch(String value) {
+		super(value);
+	}
+}

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/fa4736b6/juneau-core/src/main/java/org/apache/juneau/http/IfRange.java
----------------------------------------------------------------------
diff --git a/juneau-core/src/main/java/org/apache/juneau/http/IfRange.java b/juneau-core/src/main/java/org/apache/juneau/http/IfRange.java
new file mode 100644
index 0000000..cf2cb2b
--- /dev/null
+++ b/juneau-core/src/main/java/org/apache/juneau/http/IfRange.java
@@ -0,0 +1,95 @@
+// ***************************************************************************************************************************
+// * Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements.  See the NOTICE file *
+// * distributed with this work for additional information regarding copyright ownership.  The ASF licenses this file        *
+// * to you under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance            *
+// * with the License.  You may obtain a copy of the License at                                                              *
+// *                                                                                                                         *
+// *  http://www.apache.org/licenses/LICENSE-2.0                                                                             *
+// *                                                                                                                         *
+// * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an  *
+// * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the License for the        *
+// * specific language governing permissions and limitations under the License.                                              *
+// ***************************************************************************************************************************
+package org.apache.juneau.http;
+
+import static org.apache.juneau.internal.StringUtils.*;
+
+import org.apache.juneau.internal.*;
+
+/**
+ * Represents a parsed <l>If-Range</l> HTTP request header.
+ * <p>
+ * If the entity is unchanged, send me the part(s) that I am missing; otherwise, send me the entire new entity.
+ *
+ * <h6 class='figure'>Example</h6>
+ * <p class='bcode'>
+ * 	If-Range: "737060cd8c284d8af7ad3082f209582d"
+ * </p>
+ *
+ * <h6 class='topic'>RFC2616 Specification</h6>
+ *
+ * If a client has a partial copy of an entity in its cache, and wishes to have an up-to-date copy of the entire entity
+ * in its cache, it could use the Range request-header with a conditional GET (using either or both of
+ * If-Unmodified-Since and If-Match.)
+ * However, if the condition fails because the entity has been modified, the client would then have to make a second
+ * request to obtain the entire current entity-body.
+ * <p>
+ * The If-Range header allows a client to "short-circuit" the second request.
+ * Informally, its meaning is `if the entity is unchanged, send me the part(s) that I am missing; otherwise, send me
+ * the entire new entity'.
+ * <p class='bcode'>
+ * 	If-Range = "If-Range" ":" ( entity-tag | HTTP-date )
+ * </p>
+ * <p>
+ * If the client has no entity tag for an entity, but does have a Last- Modified date, it MAY use that date in an
+ * If-Range header.
+ * (The server can distinguish between a valid HTTP-date and any form of entity-tag by examining no more than two
+ * characters.)
+ * The If-Range header SHOULD only be used together with a Range header, and MUST be ignored if the request does not
+ * include a Range header, or if the server does not support the sub-range operation.
+ * <p>
+ * If the entity tag given in the If-Range header matches the current entity tag for the entity, then the server SHOULD
+ * provide the specified sub-range of the entity using a 206 (Partial content) response.
+ * If the entity tag does not match, then the server SHOULD return the entire entity using a 200 (OK) response.
+ */
+public final class IfRange extends HeaderString {
+
+	/**
+	 * Returns a parsed <code>If-Range</code> header.
+	 *
+	 * @param value The <code>If-Range</code> header string.
+	 * @return The parsed <code>If-Range</code> header, or <jk>null</jk> if the string was null.
+	 */
+	public static IfRange forString(String value) {
+		if (value == null)
+			return null;
+		return new IfRange(value);
+	}
+
+	private IfRange(String value) {
+		super(value);
+	}
+
+	/**
+	 * Returns this header value as a {@link java.util.Date} object.
+	 * @return This header value as a {@link java.util.Date} object, or <jk>null</jk> if the value is not a date.
+	 */
+	public java.util.Date asDate() {
+		char c0 = charAt(value, 0), c1 = charAt(value, 1);
+		if (c0 == '*' || c0 == '"' || (c0 == 'W' && c1 == '/'))
+			return null;
+		return DateUtils.parseDate(toString());
+	}
+
+	/**
+	 * Returns this header value as an {@link EntityValidator} object.
+	 * @return This header value as a {@link EntityValidator} object, or <jk>null</jk> if the value is not an entity
+	 * 	validator.
+	 */
+	public EntityValidator asValidator() {
+		char c0 = charAt(value, 0), c1 = charAt(value, 1);
+		if (c0 == '*' || c0 == '"' || (c0 == 'W' && c1 == '/'))
+			return new EntityValidator(value);
+		return null;
+	}
+}

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/fa4736b6/juneau-core/src/main/java/org/apache/juneau/http/IfUnmodifiedSince.java
----------------------------------------------------------------------
diff --git a/juneau-core/src/main/java/org/apache/juneau/http/IfUnmodifiedSince.java b/juneau-core/src/main/java/org/apache/juneau/http/IfUnmodifiedSince.java
new file mode 100644
index 0000000..a86a823
--- /dev/null
+++ b/juneau-core/src/main/java/org/apache/juneau/http/IfUnmodifiedSince.java
@@ -0,0 +1,66 @@
+// ***************************************************************************************************************************
+// * Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements.  See the NOTICE file *
+// * distributed with this work for additional information regarding copyright ownership.  The ASF licenses this file        *
+// * to you under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance            *
+// * with the License.  You may obtain a copy of the License at                                                              *
+// *                                                                                                                         *
+// *  http://www.apache.org/licenses/LICENSE-2.0                                                                             *
+// *                                                                                                                         *
+// * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an  *
+// * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the License for the        *
+// * specific language governing permissions and limitations under the License.                                              *
+// ***************************************************************************************************************************
+package org.apache.juneau.http;
+
+/**
+ * Represents a parsed <l>If-Unmodified-Since</l> HTTP request header.
+ * <p>
+ * Only send the response if the entity has not been modified since a specific time.
+ *
+ * <h6 class='figure'>Example</h6>
+ * <p class='bcode'>
+ * 	If-Unmodified-Since: Sat, 29 Oct 1994 19:43:31 GMT
+ * </p>
+ *
+ * <h6 class='topic'>RFC2616 Specification</h6>
+ * The If-Unmodified-Since request-header field is used with a method to make it conditional.
+ * If the requested resource has not been modified since the time specified in this field, the server SHOULD perform the
+ * requested operation as if the If-Unmodified-Since header were not present.
+ * <p>
+ * If the requested variant has been modified since the specified time, the server MUST NOT perform the requested
+ * operation, and MUST return a 412 (Precondition Failed).
+ * <p class='bcode'>
+ * 	If-Unmodified-Since = "If-Unmodified-Since" ":" HTTP-date
+ * </p>
+ * <p>
+ * An example of the field is:
+ * <p class='bcode'>
+ * 	If-Unmodified-Since: Sat, 29 Oct 1994 19:43:31 GMT
+ * </p>
+ * <p>
+ * If the request normally (i.e., without the If-Unmodified-Since header) would result in anything other than a 2xx or
+ * 412 status, the If-Unmodified-Since header SHOULD be ignored.
+ * <p>
+ * If the specified date is invalid, the header is ignored.
+ * <p>
+ * The result of a request having both an If-Unmodified-Since header field and either an If-None-Match or an
+ * If-Modified-Since header fields is undefined by this specification.
+ */
+public final class IfUnmodifiedSince extends HeaderDate {
+
+	/**
+	 * Returns a parsed <code>If-Unmodified-Since</code> header.
+	 *
+	 * @param value The <code>If-Unmodified-Since</code> header string.
+	 * @return The parsed <code>If-Unmodified-Since</code> header, or <jk>null</jk> if the string was null.
+	 */
+	public static IfUnmodifiedSince forString(String value) {
+		if (value == null)
+			return null;
+		return new IfUnmodifiedSince(value);
+	}
+
+	private IfUnmodifiedSince(String value) {
+		super(value);
+	}
+}

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/fa4736b6/juneau-core/src/main/java/org/apache/juneau/http/LastModified.java
----------------------------------------------------------------------
diff --git a/juneau-core/src/main/java/org/apache/juneau/http/LastModified.java b/juneau-core/src/main/java/org/apache/juneau/http/LastModified.java
new file mode 100644
index 0000000..bd49cbf
--- /dev/null
+++ b/juneau-core/src/main/java/org/apache/juneau/http/LastModified.java
@@ -0,0 +1,74 @@
+// ***************************************************************************************************************************
+// * Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements.  See the NOTICE file *
+// * distributed with this work for additional information regarding copyright ownership.  The ASF licenses this file        *
+// * to you under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance            *
+// * with the License.  You may obtain a copy of the License at                                                              *
+// *                                                                                                                         *
+// *  http://www.apache.org/licenses/LICENSE-2.0                                                                             *
+// *                                                                                                                         *
+// * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an  *
+// * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the License for the        *
+// * specific language governing permissions and limitations under the License.                                              *
+// ***************************************************************************************************************************
+package org.apache.juneau.http;
+
+/**
+ * Represents a parsed <l>Last-Modified</l> HTTP response header.
+ * <p>
+ * The last modified date for the requested object (in "HTTP-date" format as defined by RFC 7231).
+ *
+ * <h6 class='figure'>Example</h6>
+ * <p class='bcode'>
+ * 	Last-Modified: Tue, 15 Nov 1994 12:45:26 GMT
+ * </p>
+ *
+ * <h6 class='topic'>RFC2616 Specification</h6>
+ *
+ * The Last-Modified entity-header field indicates the date and time at which the origin server believes the variant was
+ * last modified.
+ * <p class='bcode'>
+ * 	Last-Modified  = "Last-Modified" ":" HTTP-date
+ * </p>
+ * <p>
+ * An example of its use is...
+ * <p class='bcode'>
+ * 	Last-Modified: Tue, 15 Nov 1994 12:45:26 GMT
+ * </p>
+ * <p>
+ * The exact meaning of this header field depends on the implementation of the origin server and the nature of the
+ * original resource.
+ * For files, it may be just the file system last-modified time.
+ * For entities with dynamically included parts, it may be the most recent of the set of last-modify times for its
+ * component parts.
+ * For database gateways, it may be the last-update time stamp of the record.
+ * For virtual objects, it may be the last time the internal state changed.
+ * <p>
+ * An origin server MUST NOT send a Last-Modified date which is later than the server's time of message origination.
+ * In such cases, where the resource's last modification would indicate some time in the future, the server MUST replace
+ * that date with the message origination date.
+ * <p>
+ * An origin server SHOULD obtain the Last-Modified value of the entity as close as possible to the time that it
+ * generates the Date value of its response.
+ * This allows a recipient to make an accurate assessment of the entity's modification time, especially if the entity
+ * changes near the time that the response is generated.
+ * <p>
+ * HTTP/1.1 servers SHOULD send Last-Modified whenever feasible.
+ */
+public final class LastModified extends HeaderDate {
+
+	/**
+	 * Returns a parsed <code>Last-Modified</code> header.
+	 *
+	 * @param value The <code>Last-Modified</code> header string.
+	 * @return The parsed <code>Last-Modified</code> header, or <jk>null</jk> if the string was null.
+	 */
+	public static LastModified forString(String value) {
+		if (value == null)
+			return null;
+		return new LastModified(value);
+	}
+
+	private LastModified(String value) {
+		super(value);
+	}
+}

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/fa4736b6/juneau-core/src/main/java/org/apache/juneau/http/Location.java
----------------------------------------------------------------------
diff --git a/juneau-core/src/main/java/org/apache/juneau/http/Location.java b/juneau-core/src/main/java/org/apache/juneau/http/Location.java
new file mode 100644
index 0000000..017ba77
--- /dev/null
+++ b/juneau-core/src/main/java/org/apache/juneau/http/Location.java
@@ -0,0 +1,63 @@
+// ***************************************************************************************************************************
+// * Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements.  See the NOTICE file *
+// * distributed with this work for additional information regarding copyright ownership.  The ASF licenses this file        *
+// * to you under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance            *
+// * with the License.  You may obtain a copy of the License at                                                              *
+// *                                                                                                                         *
+// *  http://www.apache.org/licenses/LICENSE-2.0                                                                             *
+// *                                                                                                                         *
+// * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an  *
+// * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the License for the        *
+// * specific language governing permissions and limitations under the License.                                              *
+// ***************************************************************************************************************************
+package org.apache.juneau.http;
+
+/**
+ * Represents a parsed <l>Location</l> HTTP response header.
+ * <p>
+ * Used in redirection, or when a new resource has been created.
+ *
+ * <h6 class='figure'>Example</h6>
+ * <p class='bcode'>
+ * 	Location: http://www.w3.org/pub/WWW/People.html
+ * </p>
+ *
+ * <h6 class='topic'>RFC2616 Specification</h6>
+ *
+ * The Location response-header field is used to redirect the recipient to a location other than the Request-URI for
+ * completion of the request or identification of a new resource.
+ * For 201 (Created) responses, the Location is that of the new resource which was created by the request.
+ * For 3xx responses, the location SHOULD indicate the server's preferred URI for automatic redirection to the resource.
+ * The field value consists of a single absolute URI.
+ * <p class='bcode'>
+ * 	Location       = "Location" ":" absoluteURI
+ * </p>
+ * <p>
+ * An example is:
+ * <p class='bcode'>
+ * 	Location: http://www.w3.org/pub/WWW/People.html
+ * </p>
+ * <p>
+ * Note: The Content-Location header field (section 14.14) differs from Location in that the Content-Location identifies
+ * the original location of the entity enclosed in the request.
+ * It is therefore possible for a response to contain header fields for both Location and Content-Location.
+ * Also see section 13.10 for cache requirements of some methods.
+ */
+public final class Location extends HeaderUri {
+
+	/**
+	 * Returns a parsed <code>Location</code> header.
+	 *
+	 * @param value The <code>Location</code> header string.
+	 * @return The parsed <code>Location</code> header, or <jk>null</jk> if the string was null.
+	 */
+	public static Location forString(String value) {
+		if (value == null)
+			return null;
+		return new Location(value);
+	}
+
+	private Location(String value) {
+		super(value);
+	}
+}

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/fa4736b6/juneau-core/src/main/java/org/apache/juneau/http/MaxForwards.java
----------------------------------------------------------------------
diff --git a/juneau-core/src/main/java/org/apache/juneau/http/MaxForwards.java b/juneau-core/src/main/java/org/apache/juneau/http/MaxForwards.java
new file mode 100644
index 0000000..bbe9534
--- /dev/null
+++ b/juneau-core/src/main/java/org/apache/juneau/http/MaxForwards.java
@@ -0,0 +1,65 @@
+// ***************************************************************************************************************************
+// * Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements.  See the NOTICE file *
+// * distributed with this work for additional information regarding copyright ownership.  The ASF licenses this file        *
+// * to you under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance            *
+// * with the License.  You may obtain a copy of the License at                                                              *
+// *                                                                                                                         *
+// *  http://www.apache.org/licenses/LICENSE-2.0                                                                             *
+// *                                                                                                                         *
+// * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an  *
+// * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the License for the        *
+// * specific language governing permissions and limitations under the License.                                              *
+// ***************************************************************************************************************************
+package org.apache.juneau.http;
+
+/**
+ * Represents a parsed <l>Max-Forwards</l> HTTP request header.
+ * <p>
+ * Limit the number of times the message can be forwarded through proxies or gateways.
+ *
+ * <h6 class='figure'>Example</h6>
+ * <p class='bcode'>
+ * 	Max-Forwards: 10
+ * </p>
+ *
+ * <h6 class='topic'>RFC2616 Specification</h6>
+ *
+ * The Max-Forwards request-header field provides a mechanism with the TRACE (section 9.8) and OPTIONS (section 9.2)
+ * methods to limit the number of proxies or gateways that can forward the request to the next inbound server.
+ * This can be useful when the client is attempting to trace a request chain which appears to be failing or looping in
+ * mid-chain.
+ * <p class='bcode'>
+ * 	Max-Forwards   = "Max-Forwards" ":" 1*DIGIT
+ * </p>
+ * <p>
+ * The Max-Forwards value is a decimal integer indicating the remaining number of times this request message may be
+ * forwarded.
+ * <p>
+ * Each proxy or gateway recipient of a TRACE or OPTIONS request containing a Max-Forwards header field MUST check and
+ * update its value prior to forwarding the request.
+ * If the received value is zero (0), the recipient MUST NOT forward the request; instead, it MUST respond as the final
+ * recipient.
+ * If the received Max-Forwards value is greater than zero, then the forwarded message MUST contain an updated
+ * Max-Forwards field with a value decremented by one (1).
+ * <p>
+ * The Max-Forwards header field MAY be ignored for all other methods defined by this specification and for any
+ * extension methods for which it is not explicitly referred to as part of that method definition.
+ */
+public final class MaxForwards extends HeaderInteger {
+
+	/**
+	 * Returns a parsed <code>Max-Forwards</code> header.
+	 *
+	 * @param value The <code>Max-Forwards</code> header string.
+	 * @return The parsed <code>Max-Forwards</code> header, or <jk>null</jk> if the string was null.
+	 */
+	public static MaxForwards forString(String value) {
+		if (value == null)
+			return null;
+		return new MaxForwards(value);
+	}
+
+	private MaxForwards(String value) {
+		super(value);
+	}
+}

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/fa4736b6/juneau-core/src/main/java/org/apache/juneau/http/Pragma.java
----------------------------------------------------------------------
diff --git a/juneau-core/src/main/java/org/apache/juneau/http/Pragma.java b/juneau-core/src/main/java/org/apache/juneau/http/Pragma.java
new file mode 100644
index 0000000..9c2b3e7
--- /dev/null
+++ b/juneau-core/src/main/java/org/apache/juneau/http/Pragma.java
@@ -0,0 +1,71 @@
+// ***************************************************************************************************************************
+// * Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements.  See the NOTICE file *
+// * distributed with this work for additional information regarding copyright ownership.  The ASF licenses this file        *
+// * to you under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance            *
+// * with the License.  You may obtain a copy of the License at                                                              *
+// *                                                                                                                         *
+// *  http://www.apache.org/licenses/LICENSE-2.0                                                                             *
+// *                                                                                                                         *
+// * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an  *
+// * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the License for the        *
+// * specific language governing permissions and limitations under the License.                                              *
+// ***************************************************************************************************************************
+package org.apache.juneau.http;
+
+/**
+ * Represents a parsed <l>Pragma</l> HTTP request/response header.
+ * <p>
+ * Implementation-specific fields that may have various effects anywhere along the request-response chain.
+ *
+ * <h6 class='figure'>Example</h6>
+ * <p class='bcode'>
+ * 	Pragma: no-cache
+ * </p>
+ *
+ * <h6 class='topic'>RFC2616 Specification</h6>
+ * The Pragma general-header field is used to include implementation- specific directives that might apply to any
+ * recipient along the request/response chain.
+ * All pragma directives specify optional behavior from the viewpoint of the protocol; however, some systems MAY
+ * require that behavior be consistent with the directives.
+ * <p class='bcode'>
+ * 	Pragma            = "Pragma" ":" 1#pragma-directive
+ * 	pragma-directive  = "no-cache" | extension-pragma
+ * 	extension-pragma  = token [ "=" ( token | quoted-string ) ]
+ * </p>
+ * <p>
+ * When the no-cache directive is present in a request message, an application SHOULD forward the request toward the
+ * origin server even if it has a cached copy of what is being requested.
+ * This pragma directive has the same semantics as the no-cache cache-directive (see section 14.9) and is defined here
+ * for backward compatibility with HTTP/1.0.
+ * Clients SHOULD include both header fields when a no-cache request is sent to a server not known to be HTTP/1.1
+ * compliant.
+ * <p>
+ * Pragma directives MUST be passed through by a proxy or gateway application, regardless of their significance to that
+ * application, since the directives might be applicable to all recipients along the request/response chain.
+ * It is not possible to specify a pragma for a specific recipient; however, any pragma directive not relevant to a
+ * recipient SHOULD be ignored by that recipient.
+ * <p>
+ * HTTP/1.1 caches SHOULD treat "Pragma: no-cache" as if the client had sent "Cache-Control: no-cache".
+ * No new Pragma directives will be defined in HTTP.
+ * <p>
+ * Note: because the meaning of "Pragma: no-cache as a response header field is not actually specified, it does not
+ * provide a reliable replacement for "Cache-Control: no-cache" in a response.
+ */
+public final class Pragma extends HeaderString {
+
+	/**
+	 * Returns a parsed <code>Pragma</code> header.
+	 *
+	 * @param value The <code>Pragma</code> header string.
+	 * @return The parsed <code>Pragma</code> header, or <jk>null</jk> if the string was null.
+	 */
+	public static Pragma forString(String value) {
+		if (value == null)
+			return null;
+		return new Pragma(value);
+	}
+
+	private Pragma(String value) {
+		super(value);
+	}
+}

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/fa4736b6/juneau-core/src/main/java/org/apache/juneau/http/ProxyAuthenticate.java
----------------------------------------------------------------------
diff --git a/juneau-core/src/main/java/org/apache/juneau/http/ProxyAuthenticate.java b/juneau-core/src/main/java/org/apache/juneau/http/ProxyAuthenticate.java
new file mode 100644
index 0000000..f2c8114
--- /dev/null
+++ b/juneau-core/src/main/java/org/apache/juneau/http/ProxyAuthenticate.java
@@ -0,0 +1,58 @@
+// ***************************************************************************************************************************
+// * Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements.  See the NOTICE file *
+// * distributed with this work for additional information regarding copyright ownership.  The ASF licenses this file        *
+// * to you under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance            *
+// * with the License.  You may obtain a copy of the License at                                                              *
+// *                                                                                                                         *
+// *  http://www.apache.org/licenses/LICENSE-2.0                                                                             *
+// *                                                                                                                         *
+// * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an  *
+// * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the License for the        *
+// * specific language governing permissions and limitations under the License.                                              *
+// ***************************************************************************************************************************
+package org.apache.juneau.http;
+
+/**
+ * Represents a parsed <l> Proxy-Authenticate</l> HTTP response header.
+ * <p>
+ * Request authentication to access the proxy.
+ *
+ * <h6 class='figure'>Example</h6>
+ * <p class='bcode'>
+ * 	Proxy-Authenticate: Basic
+ * </p>
+ *
+ * <h6 class='topic'>RFC2616 Specification</h6>
+ *
+ * The Proxy-Authenticate response-header field MUST be included as part of a 407 (Proxy Authentication Required)
+ * response.
+ * The field value consists of a challenge that indicates the authentication scheme and parameters applicable to the
+ * proxy for this Request-URI.
+ * <p class='bcode'>
+ * 	Proxy-Authenticate  = "Proxy-Authenticate" ":" 1#challenge
+ * </p>
+ * <p>
+ * The HTTP access authentication process is described in "HTTP Authentication: Basic and Digest Access Authentication".
+ * Unlike WWW-Authenticate, the Proxy-Authenticate header field applies only to the current connection and SHOULD NOT
+ * be passed on to downstream clients.
+ * However, an intermediate proxy might need to obtain its own credentials by requesting them from the downstream
+ * client, which in some circumstances will appear as if the proxy is forwarding the Proxy-Authenticate header field.
+ */
+public final class ProxyAuthenticate extends HeaderString {
+
+	/**
+	 * Returns a parsed <code>Proxy-Authenticate</code> header.
+	 *
+	 * @param value The <code>Proxy-Authenticate</code> header string.
+	 * @return The parsed <code>Proxy-Authenticate</code> header, or <jk>null</jk> if the string was null.
+	 */
+	public static ProxyAuthenticate forString(String value) {
+		if (value == null)
+			return null;
+		return new ProxyAuthenticate(value);
+	}
+
+	private ProxyAuthenticate(String value) {
+		super(value);
+	}
+}

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/fa4736b6/juneau-core/src/main/java/org/apache/juneau/http/ProxyAuthorization.java
----------------------------------------------------------------------
diff --git a/juneau-core/src/main/java/org/apache/juneau/http/ProxyAuthorization.java b/juneau-core/src/main/java/org/apache/juneau/http/ProxyAuthorization.java
new file mode 100644
index 0000000..74040af
--- /dev/null
+++ b/juneau-core/src/main/java/org/apache/juneau/http/ProxyAuthorization.java
@@ -0,0 +1,60 @@
+// ***************************************************************************************************************************
+// * Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements.  See the NOTICE file *
+// * distributed with this work for additional information regarding copyright ownership.  The ASF licenses this file        *
+// * to you under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance            *
+// * with the License.  You may obtain a copy of the License at                                                              *
+// *                                                                                                                         *
+// *  http://www.apache.org/licenses/LICENSE-2.0                                                                             *
+// *                                                                                                                         *
+// * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an  *
+// * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the License for the        *
+// * specific language governing permissions and limitations under the License.                                              *
+// ***************************************************************************************************************************
+package org.apache.juneau.http;
+
+/**
+ * Represents a parsed <l>Proxy-Authorization</l> HTTP request header.
+ * <p>
+ * Authorization credentials for connecting to a proxy.
+ *
+ * <h6 class='figure'>Example</h6>
+ * <p class='bcode'>
+ * 	Proxy-Authorization: Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ==
+ * </p>
+ *
+ * <h6 class='topic'>RFC2616 Specification</h6>
+ *
+ * The Proxy-Authorization request-header field allows the client to identify itself (or its user) to a proxy which
+ * requires authentication.
+ * The Proxy-Authorization field value consists of credentials containing the authentication information of the user
+ * agent for the proxy and/or realm of the resource being requested.
+ * <p class='bcode'>
+ * 	Proxy-Authorization     = "Proxy-Authorization" ":" credentials
+ * </p>
+ * <p>
+ * The HTTP access authentication process is described in "HTTP Authentication: Basic and Digest Access Authentication".
+ * Unlike Authorization, the Proxy-Authorization header field applies only to the next outbound proxy that demanded
+ * authentication using the Proxy-Authenticate field.
+ * When multiple proxies are used in a chain, the Proxy-Authorization header field is consumed by the first outbound
+ * proxy that was expecting to receive credentials.
+ * A proxy MAY relay the credentials from the client request to the next proxy if that is the mechanism by which the
+ * proxies cooperatively authenticate a given request.
+ */
+public final class ProxyAuthorization extends HeaderString {
+
+	/**
+	 * Returns a parsed <code>Proxy-Authorization</code> header.
+	 *
+	 * @param value The <code>Proxy-Authorization</code> header string.
+	 * @return The parsed <code>Proxy-Authorization</code> header, or <jk>null</jk> if the string was null.
+	 */
+	public static ProxyAuthorization forString(String value) {
+		if (value == null)
+			return null;
+		return new ProxyAuthorization(value);
+	}
+
+	private ProxyAuthorization(String value) {
+		super(value);
+	}
+}

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/fa4736b6/juneau-core/src/main/java/org/apache/juneau/http/Range.java
----------------------------------------------------------------------
diff --git a/juneau-core/src/main/java/org/apache/juneau/http/Range.java b/juneau-core/src/main/java/org/apache/juneau/http/Range.java
new file mode 100644
index 0000000..3179358
--- /dev/null
+++ b/juneau-core/src/main/java/org/apache/juneau/http/Range.java
@@ -0,0 +1,136 @@
+// ***************************************************************************************************************************
+// * Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements.  See the NOTICE file *
+// * distributed with this work for additional information regarding copyright ownership.  The ASF licenses this file        *
+// * to you under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance            *
+// * with the License.  You may obtain a copy of the License at                                                              *
+// *                                                                                                                         *
+// *  http://www.apache.org/licenses/LICENSE-2.0                                                                             *
+// *                                                                                                                         *
+// * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an  *
+// * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the License for the        *
+// * specific language governing permissions and limitations under the License.                                              *
+// ***************************************************************************************************************************
+package org.apache.juneau.http;
+
+/**
+ * Represents a parsed <l>Range</l> HTTP request header.
+ * <p>
+ * Request only part of an entity. Bytes are numbered from 0.
+ *
+ * <h6 class='figure'>Example</h6>
+ * <p class='bcode'>
+ * 	Range: bytes=500-999
+ * </p>
+ *
+ * <h6 class='topic'>RFC2616 Specification</h6>
+ *
+ * Since all HTTP entities are represented in HTTP messages as sequences of bytes, the concept of a byte range is
+ * meaningful for any HTTP entity.
+ * (However, not all clients and servers need to support byte- range operations.)
+ * <p>
+ * Byte range specifications in HTTP apply to the sequence of bytes in the entity-body (not necessarily the same as the
+ * message-body).
+ * <p>
+ * A byte range operation MAY specify a single range of bytes, or a set of ranges within a single entity.
+ * <p class='bcode'>
+ * 	ranges-specifier = byte-ranges-specifier
+ * 	byte-ranges-specifier = bytes-unit "=" byte-range-set
+ * 	byte-range-set  = 1#( byte-range-spec | suffix-byte-range-spec )
+ * 	byte-range-spec = first-byte-pos "-" [last-byte-pos]
+ * 	first-byte-pos  = 1*DIGIT
+ * 	last-byte-pos   = 1*DIGIT
+ * </p>
+ * <p>
+ * The first-byte-pos value in a byte-range-spec gives the byte-offset of the first byte in a range.
+ * The last-byte-pos value gives the byte-offset of the last byte in the range; that is, the byte positions specified
+ * are inclusive.
+ * Byte offsets start at zero.
+ * <p>
+ * If the last-byte-pos value is present, it MUST be greater than or equal to the first-byte-pos in that
+ * byte-range-spec, or the byte- range-spec is syntactically invalid.
+ * The recipient of a byte-range- set that includes one or more syntactically invalid byte-range-spec values MUST
+ * ignore the header field that includes that byte-range-set.
+ * <p>
+ * If the last-byte-pos value is absent, or if the value is greater than or equal to the current length of the
+ * entity-body, last-byte-pos is taken to be equal to one less than the current length of the entity-body in bytes.
+ * <p>
+ * By its choice of last-byte-pos, a client can limit the number of bytes retrieved without knowing the size of the
+ * entity.
+ * <p class='bcode'>
+ * 	suffix-byte-range-spec = "-" suffix-length
+ * 	suffix-length = 1*DIGIT
+ * </p>
+ * <p>
+ * A suffix-byte-range-spec is used to specify the suffix of the entity-body, of a length given by the suffix-length
+ * value.
+ * (That is, this form specifies the last N bytes of an entity-body.)
+ * If the entity is shorter than the specified suffix-length, the entire entity-body is used.
+ * <p>
+ * If a syntactically valid byte-range-set includes at least one byte- range-spec whose first-byte-pos is less than the
+ * current length of the entity-body, or at least one suffix-byte-range-spec with a non-zero suffix-length, then the
+ * byte-range-set is satisfiable.
+ * Otherwise, the byte-range-set is unsatisfiable.
+ * If the byte-range-set is unsatisfiable, the server SHOULD return a response with a status of 416 (Requested range
+ * not satisfiable).
+ * Otherwise, the server SHOULD return a response with a status of 206 (Partial Content) containing the satisfiable
+ * ranges of the entity-body.
+ * <p>
+ * Examples of byte-ranges-specifier values (assuming an entity-body of length 10000):
+ * <p class='bcode'>
+ * 	- The first 500 bytes (byte offsets 0-499, inclusive):  bytes=0-499
+ * 	- The second 500 bytes (byte offsets 500-999, inclusive):  bytes=500-999
+ * 	- The final 500 bytes (byte offsets 9500-9999, inclusive):  bytes=-500
+ * 	- Or bytes=9500-
+ * 	- The first and last bytes only (bytes 0 and 9999):  bytes=0-0,-1
+ * 	- Several legal but not canonical specifications of the second 500 bytes (byte offsets 500-999, inclusive):
+ * 	   bytes=500-600,601-999
+ * 	   bytes=500-700,601-999
+ * </p>
+ * <p>
+ * HTTP retrieval requests using conditional or unconditional GET methods MAY request one or more sub-ranges of the
+ * entity, instead of the entire entity, using the Range request header, which applies to the entity returned as the r
+ * esult of the request:
+ * <p class='bcode'>
+ * 	Range = "Range" ":" ranges-specifier
+ * </p>
+ * <p>
+ * A server MAY ignore the Range header.
+ * However, HTTP/1.1 origin servers and intermediate caches ought to support byte ranges when possible, since Range
+ * supports efficient recovery from partially failed transfers, and supports efficient partial retrieval of large
+ * entities.
+ * <p>
+ * If the server supports the Range header and the specified range or ranges are appropriate for the entity:
+ * <ul>
+ * 	<li>The presence of a Range header in an unconditional GET modifies what is returned if the GET is otherwise
+ * 		successful.
+ * 		In other words, the response carries a status code of 206 (Partial Content) instead of 200 (OK).
+ * 	<li>The presence of a Range header in a conditional GET (a request using one or both of If-Modified-Since and
+ * 		If-None-Match, or one or both of If-Unmodified-Since and If-Match) modifies what is returned if the GET is
+ * 		otherwise successful and the condition is true. It does not affect the 304 (Not Modified) response returned if
+ * 		the conditional is false.
+ * </ul>
+ * In some cases, it might be more appropriate to use the If-Range header (see section 14.27) in addition to the Range
+ * header.
+ * <p>
+ * If a proxy that supports ranges receives a Range request, forwards the request to an inbound server, and receives an
+ * entire entity in reply, it SHOULD only return the requested range to its client.
+ * It SHOULD store the entire received response in its cache if that is consistent with its cache allocation policies.
+ */
+public final class Range extends HeaderString {
+
+	/**
+	 * Returns a parsed <code>Range</code> header.
+	 *
+	 * @param value The <code>Range</code> header string.
+	 * @return The parsed <code>Range</code> header, or <jk>null</jk> if the string was null.
+	 */
+	public static Range forString(String value) {
+		if (value == null)
+			return null;
+		return new Range(value);
+	}
+
+	private Range(String value) {
+		super(value);
+	}
+}

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/fa4736b6/juneau-core/src/main/java/org/apache/juneau/http/Referer.java
----------------------------------------------------------------------
diff --git a/juneau-core/src/main/java/org/apache/juneau/http/Referer.java b/juneau-core/src/main/java/org/apache/juneau/http/Referer.java
new file mode 100644
index 0000000..55c9433
--- /dev/null
+++ b/juneau-core/src/main/java/org/apache/juneau/http/Referer.java
@@ -0,0 +1,65 @@
+// ***************************************************************************************************************************
+// * Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements.  See the NOTICE file *
+// * distributed with this work for additional information regarding copyright ownership.  The ASF licenses this file        *
+// * to you under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance            *
+// * with the License.  You may obtain a copy of the License at                                                              *
+// *                                                                                                                         *
+// *  http://www.apache.org/licenses/LICENSE-2.0                                                                             *
+// *                                                                                                                         *
+// * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an  *
+// * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the License for the        *
+// * specific language governing permissions and limitations under the License.                                              *
+// ***************************************************************************************************************************
+package org.apache.juneau.http;
+
+/**
+ * Represents a parsed <l>Referer</l> HTTP request header.
+ * <p>
+ * This is the address of the previous web page from which a link to the currently requested page was followed.
+ * (The word “referrer” has been misspelled in the RFC as well as in most implementations to the point that it has
+ * become standard usage and is considered correct terminology)
+ *
+ * <h6 class='figure'>Example</h6>
+ * <p class='bcode'>
+ * 	Referer: http://en.wikipedia.org/wiki/Main_Page
+ * </p>
+ *
+ * <h6 class='topic'>RFC2616 Specification</h6>
+ *
+ * The Referer[sic] request-header field allows the client to specify, for the server's benefit, the address (URI) of
+ * the resource from which the Request-URI was obtained (the "referrer", although the header field is misspelled.)
+ * The Referer request-header allows a server to generate lists of back-links to resources for interest, logging,
+ * optimized caching, etc.
+ * It also allows obsolete or mistyped links to be traced for maintenance.
+ * The Referer field MUST NOT be sent if the Request-URI was obtained from a source that does not have its own URI,
+ * such as input from the user keyboard.
+ * <p class='bcode'>
+ * 	Referer        = "Referer" ":" ( absoluteURI | relativeURI )
+ * </p>
+ * <p>
+ * Example:
+ * <p class='bcode'>
+ * 	Referer: http://www.w3.org/hypertext/DataSources/Overview.html
+ * </p>
+ * <p>
+ * If the field value is a relative URI, it SHOULD be interpreted relative to the Request-URI.
+ * The URI MUST NOT include a fragment. See section 15.1.3 for security considerations.
+ */
+public final class Referer extends HeaderUri {
+
+	/**
+	 * Returns a parsed <code>Referer</code> header.
+	 *
+	 * @param value The <code>Referer</code> header string.
+	 * @return The parsed <code>Referer</code> header, or <jk>null</jk> if the string was null.
+	 */
+	public static Referer forString(String value) {
+		if (value == null)
+			return null;
+		return new Referer(value);
+	}
+
+	private Referer(String value) {
+		super(value);
+	}
+}

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/fa4736b6/juneau-core/src/main/java/org/apache/juneau/http/RetryAfter.java
----------------------------------------------------------------------
diff --git a/juneau-core/src/main/java/org/apache/juneau/http/RetryAfter.java b/juneau-core/src/main/java/org/apache/juneau/http/RetryAfter.java
new file mode 100644
index 0000000..608f02e
--- /dev/null
+++ b/juneau-core/src/main/java/org/apache/juneau/http/RetryAfter.java
@@ -0,0 +1,94 @@
+// ***************************************************************************************************************************
+// * Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements.  See the NOTICE file *
+// * distributed with this work for additional information regarding copyright ownership.  The ASF licenses this file        *
+// * to you under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance            *
+// * with the License.  You may obtain a copy of the License at                                                              *
+// *                                                                                                                         *
+// *  http://www.apache.org/licenses/LICENSE-2.0                                                                             *
+// *                                                                                                                         *
+// * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an  *
+// * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the License for the        *
+// * specific language governing permissions and limitations under the License.                                              *
+// ***************************************************************************************************************************
+package org.apache.juneau.http;
+
+import static org.apache.juneau.internal.StringUtils.*;
+
+import org.apache.juneau.internal.*;
+
+/**
+ * Represents a parsed <l>Retry-After</l> HTTP response header.
+ * <p>
+ * If an entity is temporarily unavailable, this instructs the client to try again later.
+ * Value could be a specified period of time (in seconds) or a HTTP-date.
+ *
+ * <h6 class='figure'>Example</h6>
+ * <p class='bcode'>
+ * 	Retry-After: 120
+ * 	Retry-After: Fri, 07 Nov 2014 23:59:59 GMT
+ * </p>
+ *
+ * <h6 class='topic'>RFC2616 Specification</h6>
+ * The Retry-After response-header field can be used with a 503 (Service Unavailable) response to indicate how long the
+ * service is expected to be unavailable to the requesting client.
+ * This field MAY also be used with any 3xx (Redirection) response to indicate the minimum time the user-agent is asked
+ * wait before issuing the redirected request.
+ * The value of this field can be either an HTTP-date or an integer number of seconds (in decimal) after the time of the
+ * response.
+ * <p class='bcode'>
+ * 	Retry-After  = "Retry-After" ":" ( HTTP-date | delta-seconds )
+ * </p>
+ * <p>
+ * Two examples of its use are
+ * <p class='bcode'>
+ * 	Retry-After: Fri, 31 Dec 1999 23:59:59 GMT
+ * 	Retry-After: 120
+ * </p>
+ * <p>
+ * In the latter example, the delay is 2 minutes.
+ */
+public final class RetryAfter extends HeaderString {
+
+	/**
+	 * Returns a parsed <code>Retry-After</code> header.
+	 *
+	 * @param value The <code>Retry-After</code> header string.
+	 * @return The parsed <code>Retry-After</code> header, or <jk>null</jk> if the string was null.
+	 */
+	public static RetryAfter forString(String value) {
+		if (value == null)
+			return null;
+		return new RetryAfter(value);
+	}
+
+	private RetryAfter(String value) {
+		super(value);
+	}
+
+	/**
+	 * Returns this header value as a {@link java.util.Date} object.
+	 * @return This header value as a {@link java.util.Date} object, or <jk>null</jk> if the value is not a date.
+	 */
+	public java.util.Date asDate() {
+		char c0 = charAt(value, 0);
+		if (c0 >= '0' && c0 <= '9')
+			return null;
+		return DateUtils.parseDate(toString());
+	}
+
+	/**
+	 * Returns this header value as an integer.
+	 * @return This header value as a integer, or <code>-1</code> if the value is not an integer.
+	 */
+	public int asInt() {
+		char c0 = charAt(value, 0);
+		if (c0 >= '0' && c0 <= '9') {
+			try {
+				return Integer.parseInt(value);
+			} catch (NumberFormatException e) {
+				return -1;
+			}
+		}
+		return -1;
+	}
+}

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/fa4736b6/juneau-core/src/main/java/org/apache/juneau/http/Server.java
----------------------------------------------------------------------
diff --git a/juneau-core/src/main/java/org/apache/juneau/http/Server.java b/juneau-core/src/main/java/org/apache/juneau/http/Server.java
new file mode 100644
index 0000000..a8f2a13
--- /dev/null
+++ b/juneau-core/src/main/java/org/apache/juneau/http/Server.java
@@ -0,0 +1,65 @@
+// ***************************************************************************************************************************
+// * Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements.  See the NOTICE file *
+// * distributed with this work for additional information regarding copyright ownership.  The ASF licenses this file        *
+// * to you under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance            *
+// * with the License.  You may obtain a copy of the License at                                                              *
+// *                                                                                                                         *
+// *  http://www.apache.org/licenses/LICENSE-2.0                                                                             *
+// *                                                                                                                         *
+// * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an  *
+// * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the License for the        *
+// * specific language governing permissions and limitations under the License.                                              *
+// ***************************************************************************************************************************
+package org.apache.juneau.http;
+
+/**
+ * Represents a parsed <l>Server</l> HTTP response header.
+ * <p>
+ * A name for the server.
+ *
+ * <h6 class='figure'>Example</h6>
+ * <p class='bcode'>
+ * 	Server: Apache/2.4.1 (Unix)
+ * </p>
+ *
+ * <h6 class='topic'>RFC2616 Specification</h6>
+ *
+ * The Server response-header field contains information about the software used by the origin server to handle the
+ * request.
+ * The field can contain multiple product tokens (section 3.8) and comments identifying the server and any significant
+ * subproducts.
+ * The product tokens are listed in order of their significance for identifying the application.
+ * <p class='bcode'>
+ * 	Server         = "Server" ":" 1*( product | comment )
+ * </p>
+ * <p>
+ * Example:
+ * <p class='bcode'>
+ * 	Server: CERN/3.0 libwww/2.17
+ * </p>
+ * <p>
+ * If the response is being forwarded through a proxy, the proxy application MUST NOT modify the Server response-header.
+ * Instead, it SHOULD include a Via field (as described in section 14.45).
+ * <p>
+ * Note: Revealing the specific software version of the server might allow the server machine to become more vulnerable
+ * to attacks against software that is known to contain security holes.
+ * Server implementors are encouraged to make this field a configurable option.
+ */
+public final class Server extends HeaderString {
+
+	/**
+	 * Returns a parsed <code>Server</code> header.
+	 *
+	 * @param value The <code>Server</code> header string.
+	 * @return The parsed <code>Server</code> header, or <jk>null</jk> if the string was null.
+	 */
+	public static Server forString(String value) {
+		if (value == null)
+			return null;
+		return new Server(value);
+	}
+
+	private Server(String value) {
+		super(value);
+	}
+}

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/fa4736b6/juneau-core/src/main/java/org/apache/juneau/http/StringRange.java
----------------------------------------------------------------------
diff --git a/juneau-core/src/main/java/org/apache/juneau/http/StringRange.java b/juneau-core/src/main/java/org/apache/juneau/http/StringRange.java
new file mode 100644
index 0000000..d2e0fc5
--- /dev/null
+++ b/juneau-core/src/main/java/org/apache/juneau/http/StringRange.java
@@ -0,0 +1,276 @@
+// ***************************************************************************************************************************
+// * Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements.  See the NOTICE file *
+// * distributed with this work for additional information regarding copyright ownership.  The ASF licenses this file        *
+// * to you under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance            *
+// * with the License.  You may obtain a copy of the License at                                                              *
+// *                                                                                                                         *
+// *  http://www.apache.org/licenses/LICENSE-2.0                                                                             *
+// *                                                                                                                         *
+// * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an  *
+// * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the License for the        *
+// * specific language governing permissions and limitations under the License.                                              *
+// ***************************************************************************************************************************
+package org.apache.juneau.http;
+
+import java.util.*;
+import java.util.Map.*;
+
+import org.apache.juneau.annotation.*;
+import org.apache.juneau.internal.*;
+
+/**
+ * Represents a single value in a comma-delimited header value that optionally contains a quality
+ * metric for comparison and extension parameters.
+ * <p>
+ * Similar in concept to {@link MediaTypeRange} except instead of media types (e.g. <js>"text/json"</js>),
+ * it's a simple type (e.g. <js>"iso-8601"</js>).
+ * <p>
+ * An example of a type range is a value in an <code>Accept-Encoding</code> header.
+ */
+@BeanIgnore
+public final class StringRange implements Comparable<StringRange>  {
+
+	private static final StringRange[] DEFAULT = new StringRange[]{new StringRange("*")};
+
+	private final String type;
+	private final Float qValue;
+	private final Map<String,Set<String>> extensions;
+
+	/**
+	 * Parses a header such as an <code>Accept-Encoding</code> header value into an array of type ranges.
+	 * <p>
+	 * The syntax expected to be found in the referenced <code>value</code> complies with the syntax described in RFC2616, Section 14.1, as described below:
+	 * <p class='bcode'>
+	 * 	Accept-Encoding  = "Accept-Encoding" ":"
+	 * 	                   1#( codings [ ";" "q" "=" qvalue ] )
+	 * 	codings          = ( content-coding | "*" )
+	 * </p>
+	 * <p>
+	 * Examples of its use are:
+	 * <p class='bcode'>
+	 * 	Accept-Encoding: compress, gzip
+	 * 	Accept-Encoding:
+	 * 	Accept-Encoding: *
+	 * 	Accept-Encoding: compress;q=0.5, gzip;q=1.0
+	 * 	Accept-Encoding: gzip;q=1.0, identity; q=0.5, *;q=0
+	 * </p>
+	 *
+	 * @param value The value to parse.  If <jk>null</jk> or empty, returns a single <code>TypeRange</code> is returned that represents all types.
+	 * @return The type ranges described by the string.
+	 * <br>The ranges are sorted such that the most acceptable type is available at ordinal position <js>'0'</js>, and the least acceptable at position n-1.
+	 */
+	public static StringRange[] parse(String value) {
+
+		if (value == null || value.length() == 0)
+			return DEFAULT;
+
+		if (value.indexOf(',') == -1)
+			return new StringRange[]{new StringRange(value)};
+
+		Set<StringRange> ranges = new TreeSet<StringRange>();
+
+		for (String r : StringUtils.split(value, ',')) {
+			r = r.trim();
+
+			if (r.isEmpty())
+				continue;
+
+			ranges.add(new StringRange(r));
+		}
+
+		return ranges.toArray(new StringRange[ranges.size()]);
+	}
+
+	@SuppressWarnings("unchecked")
+	private StringRange(String token) {
+		Builder b = new Builder(token);
+		this.type = b.type;
+		this.qValue = b.qValue;
+		this.extensions = (b.extensions == null ? Collections.EMPTY_MAP : Collections.unmodifiableMap(b.extensions));
+	}
+
+	private static class Builder {
+		private String type;
+		private Float qValue = 1f;
+		private Map<String,Set<String>> extensions;
+
+		private Builder(String token) {
+
+			token = token.trim();
+
+			int i = token.indexOf(";q=");
+
+			if (i == -1) {
+				type = token;
+				return;
+			}
+
+			type = token.substring(0, i);
+
+			String[] tokens = token.substring(i+1).split(";");
+
+			// Only the type of the range is specified
+			if (tokens.length > 0) {
+				boolean isInExtensions = false;
+				for (int j = 0; j < tokens.length; j++) {
+					String[] parm = tokens[j].split("=");
+					if (parm.length == 2) {
+						String k = parm[0], v = parm[1];
+						if (isInExtensions) {
+							if (extensions == null)
+								extensions = new TreeMap<String,Set<String>>();
+							if (! extensions.containsKey(k))
+								extensions.put(k, new TreeSet<String>());
+							extensions.get(k).add(v);
+						} else if (k.equals("q")) {
+							qValue = new Float(v);
+							isInExtensions = true;
+						}
+					}
+				}
+			}
+		}
+	}
+
+	/**
+	 * Returns the type enclosed by this type range.
+	 *
+	 * <h5 class='section'>Examples:</h5>
+	 * <ul>
+	 * 	<li><js>"compress"</js>
+	 * 	<li><js>"gzip"</js>
+	 * 	<li><js>"*"</js>
+	 * </ul>
+	 *
+	 * @return The type of this type range, lowercased, never <jk>null</jk>.
+	 */
+	public String getType() {
+		return type;
+	}
+
+	/**
+	 * Returns the <js>'q'</js> (quality) value for this type, as described in Section 3.9 of RFC2616.
+	 * <p>
+	 * The quality value is a float between <code>0.0</code> (unacceptable) and <code>1.0</code> (most acceptable).
+	 * <p>
+	 * If 'q' value doesn't make sense for the context (e.g. this range was extracted from a <js>"content-*"</js> header, as opposed to <js>"accept-*"</js>
+	 * header, its value will always be <js>"1"</js>.
+	 *
+	 * @return The 'q' value for this type, never <jk>null</jk>.
+	 */
+	public Float getQValue() {
+		return qValue;
+	}
+
+	/**
+	 * Returns the optional set of custom extensions defined for this type.
+	 * <p>
+	 * Values are lowercase and never <jk>null</jk>.
+	 *
+	 * @return The optional list of extensions, never <jk>null</jk>.
+	 */
+	public Map<String,Set<String>> getExtensions() {
+		return extensions;
+	}
+
+	/**
+	 * Provides a string representation of this media range, suitable for use as an <code>Accept</code> header value.
+	 * <p>
+	 * The literal text generated will be all lowercase.
+	 *
+	 * @return A media range suitable for use as an Accept header value, never <code>null</code>.
+	 */
+	@Override /* Object */
+	public String toString() {
+		StringBuffer sb = new StringBuffer().append(type);
+
+		// '1' is equivalent to specifying no qValue. If there's no extensions, then we won't include a qValue.
+		if (qValue.floatValue() == 1.0) {
+			if (! extensions.isEmpty()) {
+				sb.append(";q=").append(qValue);
+				for (Entry<String,Set<String>> e : extensions.entrySet()) {
+					String k = e.getKey();
+					for (String v : e.getValue())
+						sb.append(';').append(k).append('=').append(v);
+				}
+			}
+		} else {
+			sb.append(";q=").append(qValue);
+			for (Entry<String,Set<String>> e : extensions.entrySet()) {
+				String k = e.getKey();
+				for (String v : e.getValue())
+					sb.append(';').append(k).append('=').append(v);
+			}
+		}
+		return sb.toString();
+	}
+
+	/**
+	 * Returns <jk>true</jk> if the specified object is also a <code>MediaType</code>, and has the same qValue, type, parameters, and extensions.
+	 *
+	 * @return <jk>true</jk> if object is equivalent.
+	 */
+	@Override /* Object */
+	public boolean equals(Object o) {
+
+		if (o == null || !(o instanceof StringRange))
+			return false;
+
+		if (this == o)
+			return true;
+
+		StringRange o2 = (StringRange) o;
+		return qValue.equals(o2.qValue)
+			&& type.equals(o2.type)
+			&& extensions.equals(o2.extensions);
+	}
+
+	/**
+	 * Returns a hash based on this instance's <code>media-type</code>.
+	 *
+	 * @return A hash based on this instance's <code>media-type</code>.
+	 */
+	@Override /* Object */
+	public int hashCode() {
+		return type.hashCode();
+	}
+
+	/**
+	 * Compares two MediaRanges for equality.
+	 * <p>
+	 * The values are first compared according to <code>qValue</code> values.
+	 * Should those values be equal, the <code>type</code> is then lexicographically compared (case-insensitive) in ascending order,
+	 * 	with the <js>"*"</js> type demoted last in that order.
+	 * <code>TypeRanges</code> with the same types but with extensions are promoted over those same types with no extensions.
+	 *
+	 * @param o The range to compare to.  Never <jk>null</jk>.
+	 */
+	@Override /* Comparable */
+	public int compareTo(StringRange o) {
+
+		// Compare q-values.
+		int qCompare = Float.compare(o.qValue, qValue);
+		if (qCompare != 0)
+			return qCompare;
+
+		// Compare media-types.
+		// Note that '*' comes alphabetically before letters, so just do a reverse-alphabetical comparison.
+		int i = o.type.toString().compareTo(type.toString());
+		return i;
+	}
+
+	/**
+	 * Checks if the specified type matches this range.
+	 * <p>
+	 * The type will match this range if the range type string is the same or <js>"*"</js>.
+	 *
+	 * @param type The type to match against this range.
+	 * @return <jk>true</jk> if the specified type matches this range.
+	 */
+	@SuppressWarnings("hiding")
+	public boolean matches(String type) {
+		if (qValue == 0)
+			return false;
+		return this.type.equals(type) || this.type.equals("*");
+	}
+}

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/fa4736b6/juneau-core/src/main/java/org/apache/juneau/http/TE.java
----------------------------------------------------------------------
diff --git a/juneau-core/src/main/java/org/apache/juneau/http/TE.java b/juneau-core/src/main/java/org/apache/juneau/http/TE.java
new file mode 100644
index 0000000..45cf296
--- /dev/null
+++ b/juneau-core/src/main/java/org/apache/juneau/http/TE.java
@@ -0,0 +1,97 @@
+// ***************************************************************************************************************************
+// * Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements.  See the NOTICE file *
+// * distributed with this work for additional information regarding copyright ownership.  The ASF licenses this file        *
+// * to you under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance            *
+// * with the License.  You may obtain a copy of the License at                                                              *
+// *                                                                                                                         *
+// *  http://www.apache.org/licenses/LICENSE-2.0                                                                             *
+// *                                                                                                                         *
+// * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an  *
+// * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the License for the        *
+// * specific language governing permissions and limitations under the License.                                              *
+// ***************************************************************************************************************************
+package org.apache.juneau.http;
+
+import static org.apache.juneau.http.Constants.*;
+
+import org.apache.juneau.internal.*;
+
+/**
+ * Represents a parsed <l>TE</l> HTTP request header.
+ * <p>
+ * The transfer encodings the user agent is willing to accept: the same values as for the response header field
+ * Transfer-Encoding can be used, plus the "trailers" value (related to the "chunked" transfer method) to notify the
+ * server it expects to receive additional fields in the trailer after the last, zero-sized, chunk.
+ *
+ * <h6 class='figure'>Example</h6>
+ * <p class='bcode'>
+ * 	TE: trailers, deflate
+ * </p>
+ *
+ * <h6 class='topic'>RFC2616 Specification</h6>
+ *
+ * The TE request-header field indicates what extension transfer-codings it is willing to accept in the response and
+ * whether or not it is willing to accept trailer fields in a chunked transfer-coding.
+ * Its value may consist of the keyword "trailers" and/or a comma-separated list of extension transfer-coding names
+ * with optional accept parameters (as described in section 3.6).
+ * <p class='bcode'>
+ * 	TE        = "TE" ":" #( t-codings )
+ * 	t-codings = "trailers" | ( transfer-extension [ accept-params ] )
+ * </p>
+ * The presence of the keyword "trailers" indicates that the client is willing to accept trailer fields in a chunked
+ * transfer-coding, as defined in section 3.6.1.
+ * This keyword is reserved for use with transfer-coding values even though it does not itself represent a transfer-coding.
+ * <p>
+ * Examples of its use are:
+ * <p class='bcode'>
+ * 	TE: deflate
+ * 	TE:
+ * 	TE: trailers, deflate;q=0.5
+ * </p>
+ * <p>
+ * The TE header field only applies to the immediate connection.
+ * Therefore, the keyword MUST be supplied within a Connection header field (section 14.10) whenever TE is present in
+ * an HTTP/1.1 message.
+ * <p>
+ * A server tests whether a transfer-coding is acceptable, according to a TE field, using these rules:
+ * <ol>
+ * <li>The "chunked" transfer-coding is always acceptable.
+ * 	If the keyword "trailers" is listed, the client indicates that it is willing to accept trailer fields in the
+ * 	chunked response on behalf of itself and any downstream clients.
+ * 	The implication is that, if given, the client is stating that either all downstream clients are willing to accept
+ * 	trailer fields in the forwarded response, or that it will attempt to buffer the response on behalf of downstream
+ * 	recipients.
+ * 	Note: HTTP/1.1 does not define any means to limit the size of a chunked response such that a client can be assured
+ * 	of buffering the entire response.
+ * <li>If the transfer-coding being tested is one of the transfer-codings listed in the TE field, then it is acceptable
+ * 	unless it is accompanied by a qvalue of 0. (As defined in section 3.9, a qvalue of 0 means "not acceptable.")
+ * <li>If multiple transfer-codings are acceptable, then the acceptable transfer-coding with the highest non-zero
+ * 	qvalue is preferred.
+ * 	The "chunked" transfer-coding always has a qvalue of 1.
+ * </ol>
+ * If the TE field-value is empty or if no TE field is present, the only transfer-coding is "chunked".
+ * A message with no transfer-coding is always acceptable.
+ */
+public final class TE extends HeaderRangeArray {
+
+	private static final Cache<String,TE> cache = new Cache<String,TE>(NOCACHE, CACHE_MAX_SIZE);
+
+	/**
+	 * Returns a parsed <code>Accept</code> header.
+	 *
+	 * @param value The <code>Accept</code> header string.
+	 * @return The parsed <code>Accept</code> header, or <jk>null</jk> if the string was null.
+	 */
+	public static TE forString(String value) {
+		if (value == null)
+			return null;
+		TE te = cache.get(value);
+		if (te == null)
+			te = cache.put(value, new TE(value));
+		return te;
+	}
+
+	private TE(String value) {
+		super(value);
+	}
+}

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/fa4736b6/juneau-core/src/main/java/org/apache/juneau/http/Trailer.java
----------------------------------------------------------------------
diff --git a/juneau-core/src/main/java/org/apache/juneau/http/Trailer.java b/juneau-core/src/main/java/org/apache/juneau/http/Trailer.java
new file mode 100644
index 0000000..90eb229
--- /dev/null
+++ b/juneau-core/src/main/java/org/apache/juneau/http/Trailer.java
@@ -0,0 +1,65 @@
+// ***************************************************************************************************************************
+// * Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements.  See the NOTICE file *
+// * distributed with this work for additional information regarding copyright ownership.  The ASF licenses this file        *
+// * to you under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance            *
+// * with the License.  You may obtain a copy of the License at                                                              *
+// *                                                                                                                         *
+// *  http://www.apache.org/licenses/LICENSE-2.0                                                                             *
+// *                                                                                                                         *
+// * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an  *
+// * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the License for the        *
+// * specific language governing permissions and limitations under the License.                                              *
+// ***************************************************************************************************************************
+package org.apache.juneau.http;
+
+/**
+ * Represents a parsed <l>Trailer</l> HTTP response header.
+ * <p>
+ * The Trailer general field value indicates that the given set of header fields is present in the trailer of a message
+ * encoded with chunked transfer coding.
+ *
+ * <h6 class='figure'>Example</h6>
+ * <p class='bcode'>
+ * 	Trailer: Max-Forwards
+ * </p>
+ *
+ * <h6 class='topic'>RFC2616 Specification</h6>
+ *
+ * The Trailer general field value indicates that the given set of header fields is present in the trailer of a message
+ * encoded with chunked transfer-coding.
+ * <p class='bcode'>
+ * 	Trailer  = "Trailer" ":" 1#field-name
+ * </p>
+ * <p>
+ * An HTTP/1.1 message SHOULD include a Trailer header field in a message using chunked transfer-coding with a non-empty
+ * trailer.
+ * Doing so allows the recipient to know which header fields to expect in the trailer.
+ * <p>
+ * If no Trailer header field is present, the trailer SHOULD NOT include any header fields.
+ * See section 3.6.1 for restrictions on the use of trailer fields in a "chunked" transfer-coding.
+ * <p>
+ * Message header fields listed in the Trailer header field MUST NOT include the following header fields:
+ * <ul>
+ * 	<li>Transfer-Encoding
+ * 	<li>Content-Length
+ * 	<li>Trailer
+ * </ul>
+ */
+public final class Trailer extends HeaderString {
+
+	/**
+	 * Returns a parsed <code>Trailer</code> header.
+	 *
+	 * @param value The <code>Trailer</code> header string.
+	 * @return The parsed <code>Trailer</code> header, or <jk>null</jk> if the string was null.
+	 */
+	public static Trailer forString(String value) {
+		if (value == null)
+			return null;
+		return new Trailer(value);
+	}
+
+	private Trailer(String value) {
+		super(value);
+	}
+}

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/fa4736b6/juneau-core/src/main/java/org/apache/juneau/http/TransferEncoding.java
----------------------------------------------------------------------
diff --git a/juneau-core/src/main/java/org/apache/juneau/http/TransferEncoding.java b/juneau-core/src/main/java/org/apache/juneau/http/TransferEncoding.java
new file mode 100644
index 0000000..ffcad37
--- /dev/null
+++ b/juneau-core/src/main/java/org/apache/juneau/http/TransferEncoding.java
@@ -0,0 +1,64 @@
+// ***************************************************************************************************************************
+// * Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements.  See the NOTICE file *
+// * distributed with this work for additional information regarding copyright ownership.  The ASF licenses this file        *
+// * to you under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance            *
+// * with the License.  You may obtain a copy of the License at                                                              *
+// *                                                                                                                         *
+// *  http://www.apache.org/licenses/LICENSE-2.0                                                                             *
+// *                                                                                                                         *
+// * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an  *
+// * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the License for the        *
+// * specific language governing permissions and limitations under the License.                                              *
+// ***************************************************************************************************************************
+package org.apache.juneau.http;
+
+/**
+ * Represents a parsed <l>Transfer-Encoding</l> HTTP response header.
+ * <p>
+ * The form of encoding used to safely transfer the entity to the user.
+ * Currently defined methods are: chunked, compress, deflate, gzip, identity.
+ *
+ * <h6 class='figure'>Example</h6>
+ * <p class='bcode'>
+ * 	Transfer-Encoding: chunked
+ * </p>
+ *
+ * <h6 class='topic'>RFC2616 Specification</h6>
+ *
+ * The Transfer-Encoding general-header field indicates what (if any) type of transformation has been applied to the
+ * message body in order to safely transfer it between the sender and the recipient.
+ * This differs from the content-coding in that the transfer-coding is a property of the message, not of the entity.
+ * <p class='bcode'>
+ * 	Transfer-Encoding       = "Transfer-Encoding" ":" 1#transfer-coding
+ * </p>
+ * <p>
+ * Transfer-codings are defined in section 3.6. An example is:
+ * <p class='bcode'>
+ * 	Transfer-Encoding: chunked
+ * </p>
+ * <p>
+ * If multiple encodings have been applied to an entity, the transfer-codings MUST be listed in the order in which
+ * they were applied.
+ * Additional information about the encoding parameters MAY be provided by other entity-header fields not defined by
+ * this specification.
+ * <p>
+ * Many older HTTP/1.0 applications do not understand the Transfer-Encoding header.
+ */
+public final class TransferEncoding extends HeaderString {
+
+	/**
+	 * Returns a parsed <code>Transfer-Encoding</code> header.
+	 *
+	 * @param value The <code>Transfer-Encoding</code> header string.
+	 * @return The parsed <code>Transfer-Encoding</code> header, or <jk>null</jk> if the string was null.
+	 */
+	public static TransferEncoding forString(String value) {
+		if (value == null)
+			return null;
+		return new TransferEncoding(value);
+	}
+
+	private TransferEncoding(String value) {
+		super(value);
+	}
+}


[3/4] incubator-juneau git commit: Add HTTP header classes.

Posted by ja...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/fa4736b6/juneau-core/src/main/java/org/apache/juneau/http/ContentLocation.java
----------------------------------------------------------------------
diff --git a/juneau-core/src/main/java/org/apache/juneau/http/ContentLocation.java b/juneau-core/src/main/java/org/apache/juneau/http/ContentLocation.java
new file mode 100644
index 0000000..d8b19f4
--- /dev/null
+++ b/juneau-core/src/main/java/org/apache/juneau/http/ContentLocation.java
@@ -0,0 +1,72 @@
+// ***************************************************************************************************************************
+// * Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements.  See the NOTICE file *
+// * distributed with this work for additional information regarding copyright ownership.  The ASF licenses this file        *
+// * to you under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance            *
+// * with the License.  You may obtain a copy of the License at                                                              *
+// *                                                                                                                         *
+// *  http://www.apache.org/licenses/LICENSE-2.0                                                                             *
+// *                                                                                                                         *
+// * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an  *
+// * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the License for the        *
+// * specific language governing permissions and limitations under the License.                                              *
+// ***************************************************************************************************************************
+package org.apache.juneau.http;
+
+/**
+ * Represents a parsed <l>Content-Location</l> HTTP response header.
+ * <p>
+ * An alternate location for the returned data.
+ *
+ * <h6 class='figure'>Example</h6>
+ * <p class='bcode'>
+ * 	Content-Location: /index.htm
+ * </p>
+ *
+ * <h6 class='topic'>RFC2616 Specification</h6>
+ *
+ * The Content-Location entity-header field MAY be used to supply the resource location for the entity enclosed in the
+ * message when that entity is accessible from a location separate from the requested resource's URI.
+ * A server SHOULD provide a Content-Location for the variant corresponding to the response entity; especially in the
+ * case where a resource has multiple entities associated with it, and those entities actually have separate locations
+ * by which they might be individually accessed, the server SHOULD provide a Content-Location for the particular variant
+ * which is returned.
+ * <p class='bcode'>
+ * 	Content-Location = "Content-Location" ":"
+ * 	                   ( absoluteURI | relativeURI )
+ * </p>
+ * <p>
+ * The value of Content-Location also defines the base URI for the entity.
+ * <p>
+ * The Content-Location value is not a replacement for the original requested URI; it is only a statement of the
+ * location of the resource corresponding to this particular entity at the time of the request.
+ * Future requests MAY specify the Content-Location URI as the request- URI if the desire is to identify the source of
+ * that particular entity.
+ * <p>
+ * A cache cannot assume that an entity with a Content-Location different from the URI used to retrieve it can be used
+ * to respond to later requests on that Content-Location URI.
+ * However, the Content- Location can be used to differentiate between multiple entities retrieved from a single
+ * requested resource, as described in section 13.6.
+ * <p>
+ * If the Content-Location is a relative URI, the relative URI is interpreted relative to the Request-URI.
+ * <p>
+ * The meaning of the Content-Location header in PUT or POST requests is undefined; servers are free to ignore it in
+ * those cases.
+ */
+public final class ContentLocation extends HeaderUri {
+
+	/**
+	 * Returns a parsed <code>Content-Location</code> header.
+	 *
+	 * @param value The <code>Content-Location</code> header string.
+	 * @return The parsed <code>Content-Location</code> header, or <jk>null</jk> if the string was null.
+	 */
+	public static ContentLocation forString(String value) {
+		if (value == null)
+			return null;
+		return new ContentLocation(value);
+	}
+
+	private ContentLocation(String value) {
+		super(value);
+	}
+}

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/fa4736b6/juneau-core/src/main/java/org/apache/juneau/http/ContentRange.java
----------------------------------------------------------------------
diff --git a/juneau-core/src/main/java/org/apache/juneau/http/ContentRange.java b/juneau-core/src/main/java/org/apache/juneau/http/ContentRange.java
new file mode 100644
index 0000000..d437b3b
--- /dev/null
+++ b/juneau-core/src/main/java/org/apache/juneau/http/ContentRange.java
@@ -0,0 +1,126 @@
+// ***************************************************************************************************************************
+// * Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements.  See the NOTICE file *
+// * distributed with this work for additional information regarding copyright ownership.  The ASF licenses this file        *
+// * to you under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance            *
+// * with the License.  You may obtain a copy of the License at                                                              *
+// *                                                                                                                         *
+// *  http://www.apache.org/licenses/LICENSE-2.0                                                                             *
+// *                                                                                                                         *
+// * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an  *
+// * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the License for the        *
+// * specific language governing permissions and limitations under the License.                                              *
+// ***************************************************************************************************************************
+package org.apache.juneau.http;
+
+/**
+ * Represents a parsed <l>Content-Range</l> HTTP response header.
+ * <p>
+ * Where in a full body message this partial message belongs.
+ *
+ * <h6 class='figure'>Example</h6>
+ * <p class='bcode'>
+ * 	Content-Range: bytes 21010-47021/47022
+ * </p>
+ *
+ * <h6 class='topic'>RFC2616 Specification</h6>
+ * The Content-Range entity-header is sent with a partial entity-body to specify where in the full entity-body the
+ * partial body should be applied.
+ * Range units are defined in section 3.12.
+ * <p class='bcode'>
+ * 	Content-Range = "Content-Range" ":" content-range-spec
+ * 	content-range-spec      = byte-content-range-spec
+ * 	byte-content-range-spec = bytes-unit SP
+ * 	                          byte-range-resp-spec "/"
+ * 	                          ( instance-length | "*" )
+ * 	byte-range-resp-spec = (first-byte-pos "-" last-byte-pos)
+ * 	                               | "*"
+ * 	instance-length           = 1*DIGIT
+ * </p>
+ * <p>
+ * The header SHOULD indicate the total length of the full entity-body, unless this length is unknown or difficult to
+ * determine.
+ * The asterisk "*" character means that the instance-length is unknown at the time when the response was generated.
+ * <p>
+ * Unlike byte-ranges-specifier values (see section 14.35.1), a byte- range-resp-spec MUST only specify one range, and
+ * MUST contain absolute byte positions for both the first and last byte of the range.
+ * <p>
+ * A byte-content-range-spec with a byte-range-resp-spec whose last- byte-pos value is less than its first-byte-pos
+ * value, or whose instance-length value is less than or equal to its last-byte-pos value, is invalid.
+ * The recipient of an invalid byte-content-range- spec MUST ignore it and any content transferred along with it.
+ * <p>
+ * A server sending a response with status code 416 (Requested range not satisfiable) SHOULD include a Content-Range
+ * field with a byte-range- resp-spec of "*".
+ * The instance-length specifies the current length of the selected resource.
+ * A response with status code 206 (Partial Content) MUST NOT include a Content-Range field with a byte-range-resp-spec
+ * of "*".
+ * <p>
+ * Examples of byte-content-range-spec values, assuming that the entity contains a total of 1234 bytes:
+ * <p class='bcode'>
+ * 	The first 500 bytes:
+ * 	 bytes 0-499/1234
+ * 	The second 500 bytes:
+ * 	 bytes 500-999/1234
+ * 	All except for the first 500 bytes:
+ * 	 bytes 500-1233/1234
+ * 	The last 500 bytes:
+ * 	 bytes 734-1233/1234
+ * </p>
+ * <p>
+ * When an HTTP message includes the content of a single range (for example, a response to a request for a single range,
+ * or to a request for a set of ranges that overlap without any holes), this content is transmitted with a Content-Range
+ * header, and a Content-Length header showing the number of bytes actually transferred.
+ * For example:
+ * <p class='bcode'>
+ * 	HTTP/1.1 206 Partial content
+ * 	Date: Wed, 15 Nov 1995 06:25:24 GMT
+ * 	Last-Modified: Wed, 15 Nov 1995 04:58:08 GMT
+ * 	Content-Range: bytes 21010-47021/47022
+ * 	Content-Length: 26012
+ * 	Content-Type: image/gif
+ * </p>
+ * <p>
+ * When an HTTP message includes the content of multiple ranges (for example, a response to a request for multiple
+ * non-overlapping ranges), these are transmitted as a multipart message.
+ * The multipart media type used for this purpose is "multipart/byteranges" as defined in appendix 19.2.
+ * See appendix 19.6.3 for a compatibility issue.
+ * <p>
+ * A response to a request for a single range MUST NOT be sent using the multipart/byteranges media type.
+ * A response to a request for multiple ranges, whose result is a single range, MAY be sent as a multipart/byteranges
+ * media type with one part.
+ * A client that cannot decode a multipart/byteranges message MUST NOT ask for multiple byte-ranges in a single request.
+ * <p>
+ * When a client requests multiple byte-ranges in one request, the server SHOULD return them in the order that they
+ * appeared in the request.
+ * <p>
+ * If the server ignores a byte-range-spec because it is syntactically invalid, the server SHOULD treat the request as
+ * if the invalid Range header field did not exist.
+ * (Normally, this means return a 200 response containing the full entity).
+ * <p>
+ * If the server receives a request (other than one including an If- Range request-header field) with an unsatisfiable
+ * Range request- header field
+ * (that is, all of whose byte-range-spec values have a first-byte-pos value greater than the current length of the
+ * selected resource),
+ * it SHOULD return a response code of 416 (Requested range not satisfiable) (section 10.4.17).
+ * <p>
+ * Note: clients cannot depend on servers to send a 416 (Requested range not satisfiable) response instead of a 200 (OK)
+ * response for
+ * an unsatisfiable Range request-header, since not all servers implement this request-header.
+ */
+public final class ContentRange extends HeaderString {
+
+	/**
+	 * Returns a parsed <code>Content-Range</code> header.
+	 *
+	 * @param value The <code>Content-Range</code> header string.
+	 * @return The parsed <code>Content-Range</code> header, or <jk>null</jk> if the string was null.
+	 */
+	public static ContentRange forString(String value) {
+		if (value == null)
+			return null;
+		return new ContentRange(value);
+	}
+
+	private ContentRange(String value) {
+		super(value);
+	}
+}

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/fa4736b6/juneau-core/src/main/java/org/apache/juneau/http/ContentType.java
----------------------------------------------------------------------
diff --git a/juneau-core/src/main/java/org/apache/juneau/http/ContentType.java b/juneau-core/src/main/java/org/apache/juneau/http/ContentType.java
index fcf48d8..f2a0dd4 100644
--- a/juneau-core/src/main/java/org/apache/juneau/http/ContentType.java
+++ b/juneau-core/src/main/java/org/apache/juneau/http/ContentType.java
@@ -12,56 +12,54 @@
 // ***************************************************************************************************************************
 package org.apache.juneau.http;
 
-import java.util.concurrent.*;
+import static org.apache.juneau.http.Constants.*;
+
+import org.apache.juneau.internal.*;
 
 /**
- * Represents a parsed <code>Content-Type:</code> HTTP header.
+ * Represents a parsed <l>Content-Type</l> HTTP request/response header.
  * <p>
- * The formal RFC2616 header field definition is as follows:
- * <p class='bcode'>
- * 	14.17 Content-Type
+ * The MIME type of this content.
  *
- * 	The Content-Type entity-header field indicates the media type of the
- * 	entity-body sent to the recipient or, in the case of the HEAD method,
- * 	the media type that would have been sent had the request been a GET.
- *
- * 		Content-Type   = "Content-Type" ":" media-type
+ * <h6 class='figure'>Example</h6>
+ * <p class='bcode'>
+ * 	Content-Type: text/html; charset=utf-8
+ * </p>
  *
- * 	Media types are defined in section 3.7. An example of the field is
+ * <h6 class='topic'>RFC2616 Specification</h6>
  *
+ * The Content-Type entity-header field indicates the media type of the entity-body sent to the recipient or, in the
+ * case of the HEAD method, the media type that would have been sent had the request been a GET.
+ * <p class='bcode'>
+ * 	Content-Type   = "Content-Type" ":" media-type
+ * </p>
+ * <p>
+ * Media types are defined in section 3.7.
+ * An example of the field is...
+ * <p class='bcode'>
  * 	Content-Type: text/html; charset=ISO-8859-4
  * </p>
  */
 public class ContentType extends MediaType {
 
-	private static final boolean nocache = Boolean.getBoolean("juneau.http.ContentType.nocache");
-	private static final ConcurrentHashMap<String,ContentType> cache = new ConcurrentHashMap<String,ContentType>();
+	private static Cache<String,ContentType> cache = new Cache<String,ContentType>(NOCACHE, CACHE_MAX_SIZE);
 
 	/**
 	 * Returns a parsed <code>Content-Type</code> header.
 	 *
-	 * @param s The <code>Content-Type</code> header string.
+	 * @param value The <code>Content-Type</code> header string.
 	 * @return The parsed <code>Content-Type</code> header, or <jk>null</jk> if the string was null.
 	 */
-	public static ContentType forString(String s) {
-		if (s == null)
+	public static ContentType forString(String value) {
+		if (value == null)
 			return null;
-
-		// Prevent OOM in case of DDOS
-		if (cache.size() > 1000)
-			cache.clear();
-
-		while (true) {
-			ContentType mt = cache.get(s);
-			if (mt != null)
-				return mt;
-			mt = new ContentType(s);
-			if (nocache)
-				return mt;
-			cache.putIfAbsent(s, mt);
-		}
+		ContentType ct = cache.get(value);
+		if (ct == null)
+			ct = cache.put(value, new ContentType(value));
+		return ct;
 	}
 
+
 	private ContentType(String s) {
 		super(s);
 	}

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/fa4736b6/juneau-core/src/main/java/org/apache/juneau/http/Date.java
----------------------------------------------------------------------
diff --git a/juneau-core/src/main/java/org/apache/juneau/http/Date.java b/juneau-core/src/main/java/org/apache/juneau/http/Date.java
new file mode 100644
index 0000000..21a0ba7
--- /dev/null
+++ b/juneau-core/src/main/java/org/apache/juneau/http/Date.java
@@ -0,0 +1,83 @@
+// ***************************************************************************************************************************
+// * Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements.  See the NOTICE file *
+// * distributed with this work for additional information regarding copyright ownership.  The ASF licenses this file        *
+// * to you under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance            *
+// * with the License.  You may obtain a copy of the License at                                                              *
+// *                                                                                                                         *
+// *  http://www.apache.org/licenses/LICENSE-2.0                                                                             *
+// *                                                                                                                         *
+// * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an  *
+// * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the License for the        *
+// * specific language governing permissions and limitations under the License.                                              *
+// ***************************************************************************************************************************
+package org.apache.juneau.http;
+
+/**
+ * Represents a parsed <l>Date</l> HTTP request/response header.
+ * <p>
+ * The date and time that the message was sent (in "HTTP-date" format as defined by RFC 7231).
+ *
+ * <h6 class='figure'>Example</h6>
+ * <p class='bcode'>
+ * 	Date: Tue, 15 Nov 1994 08:12:31 GMT
+ * </p>
+ *
+ * <h6 class='topic'>RFC2616 Specification</h6>
+ *
+ * The Date general-header field represents the date and time at which the message was originated, having the same
+ * semantics as orig-date in RFC 822.
+ * The field value is an HTTP-date, as described in section 3.3.1; it MUST be sent in RFC 1123 [8]-date format.
+ * <p class='bcode'>
+ * 	Date  = "Date" ":" HTTP-date
+ * </p>
+ * <p>
+ * An example is...
+ * <p class='bcode'>
+ * 	Date: Tue, 15 Nov 1994 08:12:31 GMT
+ * </p>
+ * <p>
+ * Origin servers MUST include a Date header field in all responses, except in these cases:
+ * <ol>
+ * 	<li>If the response status code is 100 (Continue) or 101 (Switching Protocols), the response MAY include a Date
+ * header field, at the server's option.
+ * 	<li>If the response status code conveys a server error, e.g. 500 (Internal Server Error) or 503 (Service
+ * Unavailable), and it is inconvenient or impossible to generate a valid Date.
+ * 	<li>If the server does not have a clock that can provide a reasonable approximation of the current time, its
+ * responses MUST NOT include a Date header field.
+ * 		In this case, the rules in section 14.18.1 MUST be followed.
+ * </ol>
+ * A received message that does not have a Date header field MUST be assigned one by the recipient if the message will
+ * be cached by that recipient or gatewayed via a protocol which requires a Date.
+ * An HTTP implementation without a clock MUST NOT cache responses without revalidating them on every use.
+ * An HTTP cache, especially a shared cache, SHOULD use a mechanism, such as NTP, to synchronize its clock with a
+ * reliable external standard.
+ * <p>
+ * Clients SHOULD only send a Date header field in messages that include an entity-body, as in the case of the PUT and
+ * POST requests, and even then it is optional.
+ * A client without a clock MUST NOT send a Date header field in a request.
+ * <p>
+ * The HTTP-date sent in a Date header SHOULD NOT represent a date and time subsequent to the generation of the message.
+ * It SHOULD represent the best available approximation of the date and time of message generation, unless the
+ * implementation has no means of generating a reasonably accurate date and time.
+ * In theory, the date ought to represent the moment just before the entity is generated.
+ * In practice, the date can be generated at any time during the message origination without affecting its semantic
+ * value.
+ */
+public final class Date extends HeaderDate {
+
+	/**
+	 * Returns a parsed <code>Date</code> header.
+	 *
+	 * @param value The <code>Date</code> header string.
+	 * @return The parsed <code>Date</code> header, or <jk>null</jk> if the string was null.
+	 */
+	public static Date forString(String value) {
+		if (value == null)
+			return null;
+		return new Date(value);
+	}
+
+	private Date(String value) {
+		super(value);
+	}
+}

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/fa4736b6/juneau-core/src/main/java/org/apache/juneau/http/ETag.java
----------------------------------------------------------------------
diff --git a/juneau-core/src/main/java/org/apache/juneau/http/ETag.java b/juneau-core/src/main/java/org/apache/juneau/http/ETag.java
new file mode 100644
index 0000000..782e2bd
--- /dev/null
+++ b/juneau-core/src/main/java/org/apache/juneau/http/ETag.java
@@ -0,0 +1,58 @@
+// ***************************************************************************************************************************
+// * Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements.  See the NOTICE file *
+// * distributed with this work for additional information regarding copyright ownership.  The ASF licenses this file        *
+// * to you under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance            *
+// * with the License.  You may obtain a copy of the License at                                                              *
+// *                                                                                                                         *
+// *  http://www.apache.org/licenses/LICENSE-2.0                                                                             *
+// *                                                                                                                         *
+// * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an  *
+// * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the License for the        *
+// * specific language governing permissions and limitations under the License.                                              *
+// ***************************************************************************************************************************
+package org.apache.juneau.http;
+
+/**
+ * Represents a parsed <l>ETag</l> HTTP response header.
+ * <p>
+ * An identifier for a specific version of a resource, often a message digest.
+ *
+ * <h6 class='figure'>Example</h6>
+ * <p class='bcode'>
+ * 	ETag: "737060cd8c284d8af7ad3082f209582d"
+ * </p>
+ *
+ * <h6 class='topic'>RFC2616 Specification</h6>
+ *
+ * The ETag response-header field provides the current value of the entity tag for the requested variant.
+ * The headers used with entity tags are described in sections 14.24, 14.26 and 14.44.
+ * The entity tag MAY be used for comparison with other entities from the same resource (see section 13.3.3).
+ * <p class='bcode'>
+ * 	ETag = "ETag" ":" entity-tag
+ * </p>
+ * <p>
+ * Examples:
+ * <p class='bcode'>
+ * 	ETag: "xyzzy"
+ * 	ETag: W/"xyzzy"
+ * 	ETag: ""
+ * </p>
+ */
+public final class ETag extends HeaderString {
+
+	/**
+	 * Returns a parsed <code>ETag</code> header.
+	 *
+	 * @param value The <code>ETag</code> header string.
+	 * @return The parsed <code>ETag</code> header, or <jk>null</jk> if the string was null.
+	 */
+	public static ETag forString(String value) {
+		if (value == null)
+			return null;
+		return new ETag(value);
+	}
+
+	private ETag(String value) {
+		super(value);
+	}
+}

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/fa4736b6/juneau-core/src/main/java/org/apache/juneau/http/EntityValidator.java
----------------------------------------------------------------------
diff --git a/juneau-core/src/main/java/org/apache/juneau/http/EntityValidator.java b/juneau-core/src/main/java/org/apache/juneau/http/EntityValidator.java
new file mode 100644
index 0000000..7dbb73d
--- /dev/null
+++ b/juneau-core/src/main/java/org/apache/juneau/http/EntityValidator.java
@@ -0,0 +1,72 @@
+// ***************************************************************************************************************************
+// * Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements.  See the NOTICE file *
+// * distributed with this work for additional information regarding copyright ownership.  The ASF licenses this file        *
+// * to you under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance            *
+// * with the License.  You may obtain a copy of the License at                                                              *
+// *                                                                                                                         *
+// *  http://www.apache.org/licenses/LICENSE-2.0                                                                             *
+// *                                                                                                                         *
+// * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an  *
+// * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the License for the        *
+// * specific language governing permissions and limitations under the License.                                              *
+// ***************************************************************************************************************************
+package org.apache.juneau.http;
+
+/**
+ * Represents a validator value.
+ * <p>
+ * <h6 class='figure'>Example</h6>
+ * <p class='bcode'>
+ * 	ETag: "123456789"    – A strong ETag validator
+ * 	ETag: W/"123456789"  – A weak ETag validator
+ * </p>
+ */
+public class EntityValidator {
+
+	private final String value;
+	private final boolean isWeak;
+
+	/**
+	 * Constructor.
+	 *
+	 * @param value The validator string value.
+	 */
+	protected EntityValidator(String value) {
+		value = value.trim();
+		isWeak = value.startsWith("W/");
+		if (isWeak)
+			value = value.substring(2);
+		if (value.length() > 1 && value.charAt(0) == '"' && value.charAt(value.length()-1) == '"')
+			value = value.substring(1, value.length()-1);
+		this.value = value;
+	}
+
+	/**
+	 * Returns the validator value stripped of quotes and weak tag.
+	 * @return The validator value.
+	 */
+	public String asString() {
+		return value;
+	}
+
+	/**
+	 * Returns <jk>true</jk> if the weak flag is present in the value.
+	 * @return <jk>true</jk> if the weak flag is present in the value.
+	 */
+	public boolean isWeak() {
+		return isWeak;
+	}
+
+	/**
+	 * Returns <jk>true</jk> if the validator string value is <code>*</code>.
+	 * @return <jk>true</jk> if the validator string value is <code>*</code>.
+	 */
+	public boolean isAny() {
+		return "*".equals(value);
+	}
+
+	@Override
+	public String toString() {
+		return (isWeak ? "W/" : "") + (isAny() ? "*" : ('"' + value + '"'));
+	}
+}

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/fa4736b6/juneau-core/src/main/java/org/apache/juneau/http/Expect.java
----------------------------------------------------------------------
diff --git a/juneau-core/src/main/java/org/apache/juneau/http/Expect.java b/juneau-core/src/main/java/org/apache/juneau/http/Expect.java
new file mode 100644
index 0000000..e5e6910
--- /dev/null
+++ b/juneau-core/src/main/java/org/apache/juneau/http/Expect.java
@@ -0,0 +1,73 @@
+// ***************************************************************************************************************************
+// * Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements.  See the NOTICE file *
+// * distributed with this work for additional information regarding copyright ownership.  The ASF licenses this file        *
+// * to you under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance            *
+// * with the License.  You may obtain a copy of the License at                                                              *
+// *                                                                                                                         *
+// *  http://www.apache.org/licenses/LICENSE-2.0                                                                             *
+// *                                                                                                                         *
+// * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an  *
+// * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the License for the        *
+// * specific language governing permissions and limitations under the License.                                              *
+// ***************************************************************************************************************************
+package org.apache.juneau.http;
+
+/**
+ * Represents a parsed <l>Expect</l> HTTP request header.
+ * <p>
+ * Indicates that particular server behaviors are required by the client.
+ *
+ * <h6 class='figure'>Example</h6>
+ * <p class='bcode'>
+ * 	Expect: 100-continue
+ * </p>
+ *
+ * <h6 class='topic'>RFC2616 Specification</h6>
+ *
+ * The Expect request-header field is used to indicate that particular server behaviors are required by the client.
+ * <p class='bcode'>
+ * 	Expect       =  "Expect" ":" 1#expectation
+ * 	expectation  =  "100-continue" | expectation-extension
+ * 	expectation-extension =  token [ "=" ( token | quoted-string )
+ * 	                         *expect-params ]
+ * 	expect-params =  ";" token [ "=" ( token | quoted-string ) ]
+ * </p>
+ * <p>
+ * A server that does not understand or is unable to comply with any of the expectation values in the Expect field of a
+ * request MUST respond with appropriate error status.
+ * The server MUST respond with a 417 (Expectation Failed) status if any of the expectations cannot be met or, if there
+ * are other problems with the request, some other 4xx status.
+ * <p>
+ * This header field is defined with extensible syntax to allow for future extensions.
+ * If a server receives a request containing an Expect field that includes an expectation-extension that it does not
+ * support, it MUST respond with a 417 (Expectation Failed) status.
+ * <p>
+ * Comparison of expectation values is case-insensitive for unquoted tokens (including the 100-continue token), and is
+ * case-sensitive for quoted-string expectation-extensions.
+ * <p>
+ * The Expect mechanism is hop-by-hop: that is, an HTTP/1.1 proxy MUST return a 417 (Expectation Failed) status if it
+ * receives a request with an expectation that it cannot meet.
+ * However, the Expect request-header itself is end-to-end; it MUST be forwarded if the request is forwarded.
+ * <p>
+ * Many older HTTP/1.0 and HTTP/1.1 applications do not understand the Expect header.
+ * <p>
+ * See section 8.2.3 for the use of the 100 (continue) status.
+ */
+public final class Expect extends HeaderString {
+
+	/**
+	 * Returns a parsed <code>Expect</code> header.
+	 *
+	 * @param value The <code>Expect</code> header string.
+	 * @return The parsed <code>Expect</code> header, or <jk>null</jk> if the string was null.
+	 */
+	public static Expect forString(String value) {
+		if (value == null)
+			return null;
+		return new Expect(value);
+	}
+
+	private Expect(String value) {
+		super(value);
+	}
+}

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/fa4736b6/juneau-core/src/main/java/org/apache/juneau/http/Expires.java
----------------------------------------------------------------------
diff --git a/juneau-core/src/main/java/org/apache/juneau/http/Expires.java b/juneau-core/src/main/java/org/apache/juneau/http/Expires.java
new file mode 100644
index 0000000..1d6cfe8
--- /dev/null
+++ b/juneau-core/src/main/java/org/apache/juneau/http/Expires.java
@@ -0,0 +1,80 @@
+// ***************************************************************************************************************************
+// * Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements.  See the NOTICE file *
+// * distributed with this work for additional information regarding copyright ownership.  The ASF licenses this file        *
+// * to you under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance            *
+// * with the License.  You may obtain a copy of the License at                                                              *
+// *                                                                                                                         *
+// *  http://www.apache.org/licenses/LICENSE-2.0                                                                             *
+// *                                                                                                                         *
+// * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an  *
+// * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the License for the        *
+// * specific language governing permissions and limitations under the License.                                              *
+// ***************************************************************************************************************************
+package org.apache.juneau.http;
+
+/**
+ * Represents a parsed <l>Expires</l> HTTP response header.
+ * <p>
+ * Gives the date/time after which the response is considered stale (in "HTTP-date" format as defined by RFC 7231).
+ *
+ * <h6 class='figure'>Example</h6>
+ * <p class='bcode'>
+ * 	Expires: Thu, 01 Dec 1994 16:00:00 GMT
+ * </p>
+ *
+ * <h6 class='topic'>RFC2616 Specification</h6>
+ * The Expires entity-header field gives the date/time after which the response is considered stale.
+ * A stale cache entry may not normally be returned by a cache (either a proxy cache or a user agent cache) unless it is
+ * first validated with the origin server
+ * (or with an intermediate cache that has a fresh copy of the entity).
+ * See section 13.2 for further discussion of the expiration model.
+ * <p>
+ * The presence of an Expires field does not imply that the original resource will change or cease to exist at, before,
+ * or after that time.
+ * <p>
+ * The format is an absolute date and time as defined by HTTP-date in section 3.3.1; it MUST be in RFC 1123 date format:
+ * <p class='bcode'>
+ * 	Expires = "Expires" ":" HTTP-date
+ * </p>
+ * <p>
+ * An example of its use is...
+ * <p class='bcode'>
+ * 	Expires: Thu, 01 Dec 1994 16:00:00 GMT
+ * </p>
+ * <p>
+ * Note: if a response includes a Cache-Control field with the max-age directive (see section 14.9.3), that directive
+ * overrides the Expires field.
+ * <p>
+ * HTTP/1.1 clients and caches MUST treat other invalid date formats, especially including the value "0", as in the past
+ * (i.e., "already expired").
+ * <p>
+ * To mark a response as "already expired," an origin server sends an Expires date that is equal to the Date header
+ * value.
+ * (See the rules for expiration calculations in section 13.2.4.)
+ * <p>
+ * To mark a response as "never expires," an origin server sends an Expires date approximately one year from the time
+ * the response is sent.
+ * HTTP/1.1 servers SHOULD NOT send Expires dates more than one year in the future.
+ * <p>
+ * The presence of an Expires header field with a date value of some time in the future on a response that otherwise
+ * would by default be non-cacheable indicates that the response is cacheable, unless indicated otherwise by a
+ * Cache-Control header field (section 14.9).
+ */
+public final class Expires extends HeaderDate {
+
+	/**
+	 * Returns a parsed <code>Expires</code> header.
+	 *
+	 * @param value The <code>Expires</code> header string.
+	 * @return The parsed <code>Expires</code> header, or <jk>null</jk> if the string was null.
+	 */
+	public static Expires forString(String value) {
+		if (value == null)
+			return null;
+		return new Expires(value);
+	}
+
+	private Expires(String value) {
+		super(value);
+	}
+}

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/fa4736b6/juneau-core/src/main/java/org/apache/juneau/http/From.java
----------------------------------------------------------------------
diff --git a/juneau-core/src/main/java/org/apache/juneau/http/From.java b/juneau-core/src/main/java/org/apache/juneau/http/From.java
new file mode 100644
index 0000000..7ac0f7a
--- /dev/null
+++ b/juneau-core/src/main/java/org/apache/juneau/http/From.java
@@ -0,0 +1,72 @@
+// ***************************************************************************************************************************
+// * Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements.  See the NOTICE file *
+// * distributed with this work for additional information regarding copyright ownership.  The ASF licenses this file        *
+// * to you under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance            *
+// * with the License.  You may obtain a copy of the License at                                                              *
+// *                                                                                                                         *
+// *  http://www.apache.org/licenses/LICENSE-2.0                                                                             *
+// *                                                                                                                         *
+// * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an  *
+// * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the License for the        *
+// * specific language governing permissions and limitations under the License.                                              *
+// ***************************************************************************************************************************
+package org.apache.juneau.http;
+
+/**
+ * Represents a parsed <l>From</l> HTTP request header.
+ * <p>
+ * The email address of the user making the request.
+ *
+ * <h6 class='figure'>Example</h6>
+ * <p class='bcode'>
+ * 	From: user@example.com
+ * </p>
+ *
+ * <h6 class='topic'>RFC2616 Specification</h6>
+ *
+ * The From request-header field, if given, SHOULD contain an Internet e-mail address for the human user who controls
+ * the requesting user agent.
+ * The address SHOULD be machine-usable, as defined by "mailbox" in RFC 822 [9] as updated by RFC 1123 [8]:
+ * <p class='bcode'>
+ * 	From   = "From" ":" mailbox
+ * </p>
+ * <p>
+ * An example is:
+ * <p class='bcode'>
+ * 	From: webmaster@w3.org
+ * </p>
+ * <p>
+ * This header field MAY be used for logging purposes and as a means for identifying the source of invalid or unwanted
+ * requests.
+ * It SHOULD NOT be used as an insecure form of access protection.
+ * The interpretation of this field is that the request is being performed on behalf of the person given, who accepts
+ * responsibility for the method performed.
+ * In particular, robot agents SHOULD include this header so that the person responsible for running the robot can be
+ * contacted if problems occur on the receiving end.
+ * <p>
+ * The Internet e-mail address in this field MAY be separate from the Internet host which issued the request.
+ * For example, when a request is passed through a proxy the original issuer's address SHOULD be used.
+ * <p>
+ * The client SHOULD NOT send the From header field without the user's approval, as it might conflict with the user's
+ * privacy interests or their site's security policy.
+ * It is strongly recommended that the user be able to disable, enable, and modify the value of this field at any time
+ * prior to a request.
+ */
+public final class From extends HeaderString {
+
+	/**
+	 * Returns a parsed <code>From</code> header.
+	 *
+	 * @param value The <code>From</code> header string.
+	 * @return The parsed <code>From</code> header, or <jk>null</jk> if the string was null.
+	 */
+	public static From forString(String value) {
+		if (value == null)
+			return null;
+		return new From(value);
+	}
+
+	private From(String value) {
+		super(value);
+	}
+}

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/fa4736b6/juneau-core/src/main/java/org/apache/juneau/http/HeaderDate.java
----------------------------------------------------------------------
diff --git a/juneau-core/src/main/java/org/apache/juneau/http/HeaderDate.java b/juneau-core/src/main/java/org/apache/juneau/http/HeaderDate.java
new file mode 100644
index 0000000..fa2b0f0
--- /dev/null
+++ b/juneau-core/src/main/java/org/apache/juneau/http/HeaderDate.java
@@ -0,0 +1,51 @@
+// ***************************************************************************************************************************
+// * Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements.  See the NOTICE file *
+// * distributed with this work for additional information regarding copyright ownership.  The ASF licenses this file        *
+// * to you under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance            *
+// * with the License.  You may obtain a copy of the License at                                                              *
+// *                                                                                                                         *
+// *  http://www.apache.org/licenses/LICENSE-2.0                                                                             *
+// *                                                                                                                         *
+// * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an  *
+// * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the License for the        *
+// * specific language governing permissions and limitations under the License.                                              *
+// ***************************************************************************************************************************
+package org.apache.juneau.http;
+
+import org.apache.juneau.internal.*;
+
+/**
+ * Category of headers that consist of a single HTTP-date.
+ * <p>
+ * <h6 class='figure'>Example</h6>
+ * <p class='bcode'>
+ * 	If-Modified-Since: Sat, 29 Oct 1994 19:43:31 GMT
+ * </p>
+ */
+public class HeaderDate {
+
+	private final java.util.Date date;
+	private final String raw;
+
+	/**
+	 * Constructor.
+	 * @param raw The raw header value.
+	 */
+	protected HeaderDate(String raw) {
+		this.raw = raw;
+		this.date = DateUtils.parseDate(raw);
+	}
+
+	/**
+	 * Returns this header value as a {@link java.util.Date}.
+	 * @return This header value as a {@link java.util.Date}, or <jk>null</jk> if the header could not be parsed.
+	 */
+	public java.util.Date asDate() {
+		return date;
+	}
+
+	@Override /* Object */
+	public String toString() {
+		return raw;
+	}
+}

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/fa4736b6/juneau-core/src/main/java/org/apache/juneau/http/HeaderEntityValidator.java
----------------------------------------------------------------------
diff --git a/juneau-core/src/main/java/org/apache/juneau/http/HeaderEntityValidator.java b/juneau-core/src/main/java/org/apache/juneau/http/HeaderEntityValidator.java
new file mode 100644
index 0000000..c20591e
--- /dev/null
+++ b/juneau-core/src/main/java/org/apache/juneau/http/HeaderEntityValidator.java
@@ -0,0 +1,47 @@
+// ***************************************************************************************************************************
+// * Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements.  See the NOTICE file *
+// * distributed with this work for additional information regarding copyright ownership.  The ASF licenses this file        *
+// * to you under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance            *
+// * with the License.  You may obtain a copy of the License at                                                              *
+// *                                                                                                                         *
+// *  http://www.apache.org/licenses/LICENSE-2.0                                                                             *
+// *                                                                                                                         *
+// * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an  *
+// * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the License for the        *
+// * specific language governing permissions and limitations under the License.                                              *
+// ***************************************************************************************************************************
+package org.apache.juneau.http;
+
+/**
+ * Category of headers that consist of a single entity validator value.
+ * <p>
+ * <h6 class='figure'>Example</h6>
+ * <p class='bcode'>
+ * 	ETag: "xyzzy"
+ * </p>
+ */
+public class HeaderEntityValidator {
+
+	private final EntityValidator value;
+
+	/**
+	 * Constructor.
+	 * @param value The raw header value.
+	 */
+	protected HeaderEntityValidator(String value) {
+		this.value = new EntityValidator(value);
+	}
+
+	/**
+	 * Returns this header value as a {@link EntityValidator} object.
+	 * @return this header value as a {@link EntityValidator} object.
+	 */
+	public EntityValidator asValidator() {
+		return value;
+	}
+
+	@Override /* Object */
+	public String toString() {
+		return value.toString();
+	}
+}

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/fa4736b6/juneau-core/src/main/java/org/apache/juneau/http/HeaderEntityValidatorArray.java
----------------------------------------------------------------------
diff --git a/juneau-core/src/main/java/org/apache/juneau/http/HeaderEntityValidatorArray.java b/juneau-core/src/main/java/org/apache/juneau/http/HeaderEntityValidatorArray.java
new file mode 100644
index 0000000..358492a
--- /dev/null
+++ b/juneau-core/src/main/java/org/apache/juneau/http/HeaderEntityValidatorArray.java
@@ -0,0 +1,55 @@
+// ***************************************************************************************************************************
+// * Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements.  See the NOTICE file *
+// * distributed with this work for additional information regarding copyright ownership.  The ASF licenses this file        *
+// * to you under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance            *
+// * with the License.  You may obtain a copy of the License at                                                              *
+// *                                                                                                                         *
+// *  http://www.apache.org/licenses/LICENSE-2.0                                                                             *
+// *                                                                                                                         *
+// * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an  *
+// * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the License for the        *
+// * specific language governing permissions and limitations under the License.                                              *
+// ***************************************************************************************************************************
+package org.apache.juneau.http;
+
+import org.apache.juneau.internal.*;
+
+/**
+ * Category of headers that consist of a comma-delimited list of entity validator values.
+ * <p>
+ * <h6 class='figure'>Example</h6>
+ * <p class='bcode'>
+ * 	If-Match: "xyzzy"
+ * 	If-Match: "xyzzy", "r2d2xxxx", "c3piozzzz"
+ * 	If-Match: *
+ * </p>
+ */
+public class HeaderEntityValidatorArray {
+
+	private final EntityValidator[] value;
+
+	/**
+	 * Constructor.
+	 * @param value The raw header value.
+	 */
+	protected HeaderEntityValidatorArray(String value) {
+		String[] s = StringUtils.split(value, ',');
+		this.value = new EntityValidator[s.length];
+		for (int i = 0; i < s.length; i++) {
+			this.value[i] = new EntityValidator(s[i]);
+		}
+	}
+
+	/**
+	 * Returns this header value as an array of {@link EntityValidator} objects.
+	 * @return this header value as an array of {@link EntityValidator} objects.
+	 */
+	public EntityValidator[] asValidators() {
+		return value;
+	}
+
+	@Override /* Object */
+	public String toString() {
+		return StringUtils.join(value, ", ");
+	}
+}

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/fa4736b6/juneau-core/src/main/java/org/apache/juneau/http/HeaderEnum.java
----------------------------------------------------------------------
diff --git a/juneau-core/src/main/java/org/apache/juneau/http/HeaderEnum.java b/juneau-core/src/main/java/org/apache/juneau/http/HeaderEnum.java
new file mode 100644
index 0000000..cccec8c
--- /dev/null
+++ b/juneau-core/src/main/java/org/apache/juneau/http/HeaderEnum.java
@@ -0,0 +1,70 @@
+// ***************************************************************************************************************************
+// * Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements.  See the NOTICE file *
+// * distributed with this work for additional information regarding copyright ownership.  The ASF licenses this file        *
+// * to you under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance            *
+// * with the License.  You may obtain a copy of the License at                                                              *
+// *                                                                                                                         *
+// *  http://www.apache.org/licenses/LICENSE-2.0                                                                             *
+// *                                                                                                                         *
+// * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an  *
+// * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the License for the        *
+// * specific language governing permissions and limitations under the License.                                              *
+// ***************************************************************************************************************************
+package org.apache.juneau.http;
+
+/**
+ * Category of headers that consist of a single enum value.
+ * <p>
+ * <h6 class='figure'>Example</h6>
+ * <p class='bcode'>
+ * 	Accept-Ranges: bytes
+ * </p>
+ * @param <E> The enum type.
+ */
+public class HeaderEnum<E extends Enum<E>> {
+
+	private final String value;
+	private final E enumValue;
+
+	/**
+	 * Constructor.
+	 * @param value The raw header value.
+	 * @param enumClass The enum class.
+	 * @param def The default enum value if the value could not be parsed.
+	 */
+	protected HeaderEnum(String value, Class<E> enumClass, E def) {
+		this.value = value;
+		E _enumValue = def;
+		try {
+			_enumValue = Enum.valueOf(enumClass, value.toUpperCase());
+		} catch (Exception e) {
+			_enumValue = def;
+		}
+		this.enumValue = _enumValue;
+	}
+
+	/**
+	 * Returns <jk>true</jk> if the specified value is the same using {@link String#equalsIgnoreCase(String)}.
+	 *
+	 * @return <jk>true</jk> if the specified value is the same.
+	 */
+	public E asEnum() {
+		return enumValue;
+	}
+
+	/**
+	 * Returns this header as a simple string value.
+	 * <p>
+	 * Functionally equivalent to calling {@link #toString()}.
+	 *
+	 * @return This header as a simple string.
+	 */
+	public String asString() {
+		return value;
+	}
+
+	@Override /* Object */
+	public String toString() {
+		return value == null ? "" : value;
+	}
+}

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/fa4736b6/juneau-core/src/main/java/org/apache/juneau/http/HeaderInteger.java
----------------------------------------------------------------------
diff --git a/juneau-core/src/main/java/org/apache/juneau/http/HeaderInteger.java b/juneau-core/src/main/java/org/apache/juneau/http/HeaderInteger.java
new file mode 100644
index 0000000..5b23064
--- /dev/null
+++ b/juneau-core/src/main/java/org/apache/juneau/http/HeaderInteger.java
@@ -0,0 +1,59 @@
+// ***************************************************************************************************************************
+// * Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements.  See the NOTICE file *
+// * distributed with this work for additional information regarding copyright ownership.  The ASF licenses this file        *
+// * to you under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance            *
+// * with the License.  You may obtain a copy of the License at                                                              *
+// *                                                                                                                         *
+// *  http://www.apache.org/licenses/LICENSE-2.0                                                                             *
+// *                                                                                                                         *
+// * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an  *
+// * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the License for the        *
+// * specific language governing permissions and limitations under the License.                                              *
+// ***************************************************************************************************************************
+package org.apache.juneau.http;
+
+/**
+ * Category of headers that consist of a single integer value.
+ * <p>
+ * <h6 class='figure'>Example</h6>
+ * <p class='bcode'>
+ * 	Age: 300
+ * </p>
+ */
+public class HeaderInteger {
+
+	private final int value;
+
+	/**
+	 * Constructor.
+	 * @param value The raw header value.
+	 */
+	protected HeaderInteger(String value) {
+		int _value = 0;
+		try {
+			_value = Integer.parseInt(value);
+		} catch (NumberFormatException e) {
+			try {
+				Long.parseLong(value);
+				_value = Integer.MAX_VALUE;
+			} catch (NumberFormatException e2) {}
+		}
+		this.value = _value;
+	}
+
+	/**
+	 * Returns this header as a simple string value.
+	 * <p>
+	 * Functionally equivalent to calling {@link #toString()}.
+	 *
+	 * @return This header as a simple string.
+	 */
+	public int asInt() {
+		return value;
+	}
+
+	@Override /* Object */
+	public String toString() {
+		return String.valueOf(value);
+	}
+}

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/fa4736b6/juneau-core/src/main/java/org/apache/juneau/http/HeaderRangeArray.java
----------------------------------------------------------------------
diff --git a/juneau-core/src/main/java/org/apache/juneau/http/HeaderRangeArray.java b/juneau-core/src/main/java/org/apache/juneau/http/HeaderRangeArray.java
new file mode 100644
index 0000000..0163957
--- /dev/null
+++ b/juneau-core/src/main/java/org/apache/juneau/http/HeaderRangeArray.java
@@ -0,0 +1,74 @@
+// ***************************************************************************************************************************
+// * Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements.  See the NOTICE file *
+// * distributed with this work for additional information regarding copyright ownership.  The ASF licenses this file        *
+// * to you under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance            *
+// * with the License.  You may obtain a copy of the License at                                                              *
+// *                                                                                                                         *
+// *  http://www.apache.org/licenses/LICENSE-2.0                                                                             *
+// *                                                                                                                         *
+// * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an  *
+// * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the License for the        *
+// * specific language governing permissions and limitations under the License.                                              *
+// ***************************************************************************************************************************
+package org.apache.juneau.http;
+
+import java.util.*;
+
+import org.apache.juneau.internal.*;
+
+/**
+ * Category of headers that consist of simple comma-delimited lists of strings with q-values.
+ * <p>
+ * <h6 class='figure'>Example</h6>
+ * <p class='bcode'>
+ * 	Accept-Encoding: compress;q=0.5, gzip;q=1.0
+ * </p>
+ */
+public class HeaderRangeArray {
+
+	final StringRange[] typeRanges;
+	private final List<StringRange> typeRangesList;
+
+	/**
+	 * Constructor.
+	 * @param value The raw header value.
+	 */
+	protected HeaderRangeArray(String value) {
+		this.typeRanges = StringRange.parse(value);
+		this.typeRangesList = Collections.unmodifiableList(Arrays.asList(typeRanges));
+	}
+
+	/**
+	 * Given a list of type values, returns the best match for this header.
+	 *
+	 * @param types The types to match against.
+	 * @return The index into the array of the best match, or <code>-1</code> if no suitable matches could be found.
+	 */
+	public int findMatch(String[] types) {
+
+		// Type ranges are ordered by 'q'.
+		// So we only need to search until we've found a match.
+		for (StringRange mr : typeRanges)
+			for (int i = 0; i < types.length; i++)
+				if (mr.matches(types[i]))
+					return i;
+
+		return -1;
+	}
+
+	/**
+	 * Returns the list of the types ranges that make up this header.
+	 * <p>
+	 * The types ranges in the list are sorted by their q-value in descending order.
+	 *
+	 * @return An unmodifiable list of type ranges.
+	 */
+	public List<StringRange> asSimpleRanges() {
+		return typeRangesList;
+	}
+
+	@Override /* Object */
+	public String toString() {
+		return StringUtils.join(typeRanges, ',');
+	}
+}

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/fa4736b6/juneau-core/src/main/java/org/apache/juneau/http/HeaderString.java
----------------------------------------------------------------------
diff --git a/juneau-core/src/main/java/org/apache/juneau/http/HeaderString.java b/juneau-core/src/main/java/org/apache/juneau/http/HeaderString.java
new file mode 100644
index 0000000..6e34304
--- /dev/null
+++ b/juneau-core/src/main/java/org/apache/juneau/http/HeaderString.java
@@ -0,0 +1,72 @@
+// ***************************************************************************************************************************
+// * Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements.  See the NOTICE file *
+// * distributed with this work for additional information regarding copyright ownership.  The ASF licenses this file        *
+// * to you under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance            *
+// * with the License.  You may obtain a copy of the License at                                                              *
+// *                                                                                                                         *
+// *  http://www.apache.org/licenses/LICENSE-2.0                                                                             *
+// *                                                                                                                         *
+// * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an  *
+// * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the License for the        *
+// * specific language governing permissions and limitations under the License.                                              *
+// ***************************************************************************************************************************
+package org.apache.juneau.http;
+
+import org.apache.juneau.internal.*;
+
+/**
+ * Category of headers that consist of a single string value.
+ * <p>
+ * <h6 class='figure'>Example</h6>
+ * <p class='bcode'>
+ * 	Accept-Ranges: bytes
+ * </p>
+ */
+public class HeaderString {
+
+	final String value;
+
+	/**
+	 * Constructor.
+	 * @param value The raw header value.
+	 */
+	protected HeaderString(String value) {
+		this.value = StringUtils.trim(value);
+	}
+
+	/**
+	 * Returns <jk>true</jk> if the specified value is the same using {@link String#equalsIgnoreCase(String)}.
+	 *
+	 * @param compare The value to compare against.
+	 * @return <jk>true</jk> if the specified value is the same.
+	 */
+	public boolean eqIC(String compare) {
+		return value.equalsIgnoreCase(compare);
+	}
+
+	/**
+	 * Returns <jk>true</jk> if the specified value is the same using {@link String#equals(Object)}.
+	 *
+	 * @param compare The value to compare against.
+	 * @return <jk>true</jk> if the specified value is the same.
+	 */
+	public boolean eq(String compare) {
+		return value.equals(compare);
+	}
+
+	/**
+	 * Returns this header as a simple string value.
+	 * <p>
+	 * Functionally equivalent to calling {@link #toString()}.
+	 *
+	 * @return This header as a simple string.
+	 */
+	public String asString() {
+		return value;
+	}
+
+	@Override /* Object */
+	public String toString() {
+		return value == null ? "" : value;
+	}
+}

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/fa4736b6/juneau-core/src/main/java/org/apache/juneau/http/HeaderStringArray.java
----------------------------------------------------------------------
diff --git a/juneau-core/src/main/java/org/apache/juneau/http/HeaderStringArray.java b/juneau-core/src/main/java/org/apache/juneau/http/HeaderStringArray.java
new file mode 100644
index 0000000..803cd66
--- /dev/null
+++ b/juneau-core/src/main/java/org/apache/juneau/http/HeaderStringArray.java
@@ -0,0 +1,80 @@
+// ***************************************************************************************************************************
+// * Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements.  See the NOTICE file *
+// * distributed with this work for additional information regarding copyright ownership.  The ASF licenses this file        *
+// * to you under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance            *
+// * with the License.  You may obtain a copy of the License at                                                              *
+// *                                                                                                                         *
+// *  http://www.apache.org/licenses/LICENSE-2.0                                                                             *
+// *                                                                                                                         *
+// * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an  *
+// * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the License for the        *
+// * specific language governing permissions and limitations under the License.                                              *
+// ***************************************************************************************************************************
+package org.apache.juneau.http;
+
+import org.apache.juneau.internal.*;
+
+/**
+ * Category of headers that consist of a comma-delimited list of string values.
+ * <p>
+ * <h6 class='figure'>Example</h6>
+ * <p class='bcode'>
+ * 	Allow: GET, PUT
+ * </p>
+ */
+public class HeaderStringArray {
+
+	private final String[] value;
+
+	/**
+	 * Constructor.
+	 * @param value The raw header value.
+	 */
+	protected HeaderStringArray(String value) {
+		this.value = StringUtils.split(value, ',');
+	}
+
+	/**
+	 * Returns this header as a simple string value.
+	 * <p>
+	 * Functionally equivalent to calling {@link #toString()}.
+	 *
+	 * @return This header as a simple string.
+	 */
+	public String asString() {
+		return StringUtils.join(value, ',');
+	}
+
+	/**
+	 * Returns <jk>true</jk> if this header contains the specified value.
+	 *
+	 * @param val The value to check for.
+	 * @return <jk>true</jk> if this header contains the specified value.
+	 */
+	public boolean contains(String val) {
+		if (val != null)
+			for (String v : value)
+				if (val.equals(v))
+					return true;
+		return false;
+	}
+
+	/**
+	 * Returns <jk>true</jk> if this header contains the specified value using {@link String#equalsIgnoreCase(String)}.
+	 *
+	 * @param val The value to check for.
+	 * @return <jk>true</jk> if this header contains the specified value.
+	 */
+	public boolean containsIC(String val) {
+		if (val != null)
+			for (String v : value)
+				if (val.equalsIgnoreCase(v))
+					return true;
+		return false;
+	}
+
+	@Override /* Object */
+	public String toString() {
+		return asString();
+	}
+}

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/fa4736b6/juneau-core/src/main/java/org/apache/juneau/http/HeaderUri.java
----------------------------------------------------------------------
diff --git a/juneau-core/src/main/java/org/apache/juneau/http/HeaderUri.java b/juneau-core/src/main/java/org/apache/juneau/http/HeaderUri.java
new file mode 100644
index 0000000..d38deb2
--- /dev/null
+++ b/juneau-core/src/main/java/org/apache/juneau/http/HeaderUri.java
@@ -0,0 +1,62 @@
+// ***************************************************************************************************************************
+// * Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements.  See the NOTICE file *
+// * distributed with this work for additional information regarding copyright ownership.  The ASF licenses this file        *
+// * to you under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance            *
+// * with the License.  You may obtain a copy of the License at                                                              *
+// *                                                                                                                         *
+// *  http://www.apache.org/licenses/LICENSE-2.0                                                                             *
+// *                                                                                                                         *
+// * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an  *
+// * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the License for the        *
+// * specific language governing permissions and limitations under the License.                                              *
+// ***************************************************************************************************************************
+package org.apache.juneau.http;
+
+import java.net.*;
+
+import org.apache.juneau.internal.*;
+
+/**
+ * Category of headers that consist of a single URL value.
+ * <p>
+ * <h6 class='figure'>Example</h6>
+ * <p class='bcode'>
+ * 	Location: http://www.w3.org/pub/WWW/People.html
+ * </p>
+ */
+public class HeaderUri{
+
+	final String value;
+
+	/**
+	 * Constructor.
+	 * @param value The raw header value.
+	 */
+	protected HeaderUri(String value) {
+		this.value = StringUtils.trim(value);
+	}
+
+	/**
+	 * Returns this header as a {@link URI}.
+	 * @return This header as a {@link URI}.
+	 */
+	public URI asURI() {
+		return URI.create(toString());
+	}
+
+	/**
+	 * Returns this header as a simple string value.
+	 * <p>
+	 * Functionally equivalent to calling {@link #toString()}.
+	 *
+	 * @return This header as a simple string.
+	 */
+	public String asString() {
+		return value;
+	}
+
+	@Override /* Object */
+	public String toString() {
+		return value == null ? "" : value;
+	}
+}

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/fa4736b6/juneau-core/src/main/java/org/apache/juneau/http/Host.java
----------------------------------------------------------------------
diff --git a/juneau-core/src/main/java/org/apache/juneau/http/Host.java b/juneau-core/src/main/java/org/apache/juneau/http/Host.java
new file mode 100644
index 0000000..cefac84
--- /dev/null
+++ b/juneau-core/src/main/java/org/apache/juneau/http/Host.java
@@ -0,0 +1,75 @@
+// ***************************************************************************************************************************
+// * Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements.  See the NOTICE file *
+// * distributed with this work for additional information regarding copyright ownership.  The ASF licenses this file        *
+// * to you under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance            *
+// * with the License.  You may obtain a copy of the License at                                                              *
+// *                                                                                                                         *
+// *  http://www.apache.org/licenses/LICENSE-2.0                                                                             *
+// *                                                                                                                         *
+// * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an  *
+// * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the License for the        *
+// * specific language governing permissions and limitations under the License.                                              *
+// ***************************************************************************************************************************
+package org.apache.juneau.http;
+
+/**
+ * Represents a parsed <l>Host</l> HTTP request header.
+ * <p>
+ * The domain name of the server (for virtual hosting), and the TCP port number on which the server is listening.
+ * The port number may be omitted if the port is the standard port for the service requested.
+ * Mandatory since HTTP/1.1.
+ *
+ * <h6 class='figure'>Example</h6>
+ * <p class='bcode'>
+ * 	Host: en.wikipedia.org:8080
+ * 	Host: en.wikipedia.org
+ * </p>
+ *
+ * <h6 class='topic'>RFC2616 Specification</h6>
+ *
+ * The Host request-header field specifies the Internet host and port number of the resource being requested, as
+ * obtained from the original URI given by the user or referring resource (generally an HTTP URL, as described in
+ * section 3.2.2).
+ * The Host field value MUST represent the naming authority of the origin server or gateway given by the original URL.
+ * This allows the origin server or gateway to differentiate between internally-ambiguous URLs, such as the root "/" URL
+ * of a server for multiple host names on a single IP address.
+ * <p class='bcode'>
+ * 	Host = "Host" ":" host [ ":" port ] ; Section 3.2.2
+ * </p>
+ * <p>
+ * A "host" without any trailing port information implies the default port for the service requested (e.g., "80" for an
+ * HTTP URL).
+ * For example, a request on the origin server for <http://www.w3.org/pub/WWW/> would properly include:
+ * <p class='bcode'>
+ * 	GET /pub/WWW/ HTTP/1.1
+ * 	Host: www.w3.org
+ * </p>
+ * <p>
+ * A client MUST include a Host header field in all HTTP/1.1 request messages.
+ * If the requested URI does not include an Internet host name for the service being requested, then the Host header
+ * field MUST be given with an empty value.
+ * An HTTP/1.1 proxy MUST ensure that any request message it forwards does contain an appropriate Host header field that
+ * identifies the service being requested by the proxy.
+ * All Internet-based HTTP/1.1 servers MUST respond with a 400 (Bad Request) status code to any HTTP/1.1 request
+ * message which lacks a Host header field.
+ * <p>
+ * See sections 5.2 and 19.6.1.1 for other requirements relating to Host.
+ */
+public final class Host extends HeaderString {
+
+	/**
+	 * Returns a parsed <code>Host</code> header.
+	 *
+	 * @param value The <code>Host</code> header string.
+	 * @return The parsed <code>Host</code> header, or <jk>null</jk> if the string was null.
+	 */
+	public static Host forString(String value) {
+		if (value == null)
+			return null;
+		return new Host(value);
+	}
+
+	private Host(String value) {
+		super(value);
+	}
+}

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/fa4736b6/juneau-core/src/main/java/org/apache/juneau/http/IfMatch.java
----------------------------------------------------------------------
diff --git a/juneau-core/src/main/java/org/apache/juneau/http/IfMatch.java b/juneau-core/src/main/java/org/apache/juneau/http/IfMatch.java
new file mode 100644
index 0000000..a4aab7f
--- /dev/null
+++ b/juneau-core/src/main/java/org/apache/juneau/http/IfMatch.java
@@ -0,0 +1,90 @@
+// ***************************************************************************************************************************
+// * Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements.  See the NOTICE file *
+// * distributed with this work for additional information regarding copyright ownership.  The ASF licenses this file        *
+// * to you under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance            *
+// * with the License.  You may obtain a copy of the License at                                                              *
+// *                                                                                                                         *
+// *  http://www.apache.org/licenses/LICENSE-2.0                                                                             *
+// *                                                                                                                         *
+// * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an  *
+// * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the License for the        *
+// * specific language governing permissions and limitations under the License.                                              *
+// ***************************************************************************************************************************
+package org.apache.juneau.http;
+
+/**
+ * Represents a parsed <l>If-Match</l> HTTP request header.
+ * <p>
+ * Only perform the action if the client supplied entity matches the same entity on the server.
+ * This is mainly for methods like PUT to only update a resource if it has not been modified since the user last
+ * updated it.
+ *
+ * <h6 class='figure'>Example</h6>
+ * <p class='bcode'>
+ * 	If-Match: "737060cd8c284d8af7ad3082f209582d"
+ * </p>
+ *
+ * <h6 class='topic'>RFC2616 Specification</h6>
+ *
+ * The If-Match request-header field is used with a method to make it conditional.
+ * A client that has one or more entities previously obtained from the resource can verify that one of those entities
+ * is current by including a list of their associated entity tags in the If-Match header field.
+ * Entity tags are defined in section 3.11.
+ * The purpose of this feature is to allow efficient updates of cached information with a minimum amount of transaction
+ * overhead.
+ * It is also used, on updating requests, to prevent inadvertent modification of the wrong version of a resource.
+ * As a special case, the value "*" matches any current entity of the resource.
+ * <p class='bcode'>
+ * 	If-Match = "If-Match" ":" ( "*" | 1#entity-tag )
+ * </p>
+ * <p>
+ * If any of the entity tags match the entity tag of the entity that would have been returned in the response to a
+ * similar GET request (without the If-Match header) on that resource, or if "*" is given and any current entity exists
+ * for that resource, then the server MAY perform the requested method as if the If-Match header field did not exist.
+ * <p>
+ * A server MUST use the strong comparison function (see section 13.3.3) to compare the entity tags in If-Match.
+ * <p>
+ * If none of the entity tags match, or if "*" is given and no current entity exists, the server MUST NOT perform the
+ * requested method, and MUST return a 412 (Precondition Failed) response.
+ * This behavior is most useful when the client wants to prevent an updating method, such as PUT, from modifying a
+ * resource that has changed since the client last retrieved it.
+ * <p>
+ * If the request would, without the If-Match header field, result in anything other than a 2xx or 412 status, then the
+ * If-Match header MUST be ignored.
+ * <p>
+ * The meaning of "If-Match: *" is that the method SHOULD be performed if the representation selected by the origin
+ * server (or by a cache, possibly using the Vary mechanism, see section 14.44) exists, and MUST NOT be performed if the
+ * representation does not exist.
+ * <p>
+ * A request intended to update a resource (e.g., a PUT) MAY include an If-Match header field to signal that the request
+ * method MUST NOT be applied if the entity corresponding to the If-Match value (a single entity tag) is no longer a
+ * representation of that resource.
+ * This allows the user to indicate that they do not wish the request to be successful if the resource has been changed
+ * without their knowledge.
+ * Examples:
+ * <p class='bcode'>
+ * 	If-Match: "xyzzy"
+ * 	If-Match: "xyzzy", "r2d2xxxx", "c3piozzzz"
+ * 	If-Match: *
+ * </p>
+ * The result of a request having both an If-Match header field and either an If-None-Match or an If-Modified-Since
+ * header fields is undefined by this specification.
+ */
+public final class IfMatch extends HeaderEntityValidatorArray {
+
+	/**
+	 * Returns a parsed <code>If-Match</code> header.
+	 *
+	 * @param value The <code>If-Match</code> header string.
+	 * @return The parsed <code>If-Match</code> header, or <jk>null</jk> if the string was null.
+	 */
+	public static IfMatch forString(String value) {
+		if (value == null)
+			return null;
+		return new IfMatch(value);
+	}
+
+	private IfMatch(String value) {
+		super(value);
+	}
+}

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/fa4736b6/juneau-core/src/main/java/org/apache/juneau/http/IfModifiedSince.java
----------------------------------------------------------------------
diff --git a/juneau-core/src/main/java/org/apache/juneau/http/IfModifiedSince.java b/juneau-core/src/main/java/org/apache/juneau/http/IfModifiedSince.java
new file mode 100644
index 0000000..28f1ef4
--- /dev/null
+++ b/juneau-core/src/main/java/org/apache/juneau/http/IfModifiedSince.java
@@ -0,0 +1,92 @@
+// ***************************************************************************************************************************
+// * Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements.  See the NOTICE file *
+// * distributed with this work for additional information regarding copyright ownership.  The ASF licenses this file        *
+// * to you under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance            *
+// * with the License.  You may obtain a copy of the License at                                                              *
+// *                                                                                                                         *
+// *  http://www.apache.org/licenses/LICENSE-2.0                                                                             *
+// *                                                                                                                         *
+// * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an  *
+// * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the License for the        *
+// * specific language governing permissions and limitations under the License.                                              *
+// ***************************************************************************************************************************
+package org.apache.juneau.http;
+
+/**
+ * Represents a parsed <l>If-Modified-Since</l> HTTP request header.
+ * <p>
+ * Allows a 304 Not Modified to be returned if content is unchanged.
+ *
+ * <h6 class='figure'>Example</h6>
+ * <p class='bcode'>
+ * 	If-Modified-Since: Sat, 29 Oct 1994 19:43:31 GMT
+ * </p>
+ *
+ * <h6 class='topic'>RFC2616 Specification</h6>
+ *
+ * The If-Modified-Since request-header field is used with a method to make it conditional:
+ * if the requested variant has not been modified since the time specified in this field, an entity will not be returned
+ * from the server; instead, a 304 (not modified) response will be returned without any message-body.
+ * <p class='bcode'>
+ * 	If-Modified-Since = "If-Modified-Since" ":" HTTP-date
+ * </p>
+ * <p>
+ * An example of the field is:
+ * <p class='bcode'>
+ * 	If-Modified-Since: Sat, 29 Oct 1994 19:43:31 GMT
+ * </p>
+ * <p>
+ * A GET method with an If-Modified-Since header and no Range header requests that the identified entity be transferred
+ * only if it has been modified since the date given by the If-Modified-Since header.
+ * The algorithm for determining this includes the following cases:
+ * <ol>
+ * 	<li>If the request would normally result in anything other than a 200 (OK) status, or if the passed
+ * 		If-Modified-Since date is invalid, the response is exactly the same as for a normal GET.
+ * 		A date which is later than the server's current time is invalid.
+ * 	<li>If the variant has been modified since the If-Modified-Since date, the response is exactly the same as for a
+ * 		normal GET.
+ * 	<li>If the variant has not been modified since a valid If-Modified-Since date, the server SHOULD return a 304
+ * 		(Not Modified) response.
+ * </ol>
+ * The purpose of this feature is to allow efficient updates of cached information with a minimum amount of transaction
+ * overhead.
+ * <p>
+ * Note: The Range request-header field modifies the meaning of If-Modified-Since; see section 14.35 for full details.
+ * <p>
+ * Note: If-Modified-Since times are interpreted by the server, whose clock might not be synchronized with the client.
+ * <p>
+ * Note: When handling an If-Modified-Since header field, some servers will use an exact date comparison function,
+ * rather than a less-than function, for deciding whether to send a 304 (Not Modified) response.
+ * To get best results when sending an If-Modified-Since header field for cache validation, clients are
+ * advised to use the exact date string received in a previous Last-Modified header field whenever possible.
+ * <p>
+ * Note: If a client uses an arbitrary date in the If-Modified-Since header instead of a date taken from the
+ * Last-Modified header for the same request, the client should be aware of the fact that this date is interpreted in
+ * the server's understanding of time.
+ * The client should consider unsynchronized clocks and rounding problems due to the different encodings of time between
+ * the client and server.
+ * This includes the possibility of race conditions if the document has changed between the time it was first requested
+ * and the If-Modified-Since date of a subsequent request, and the possibility of clock-skew-related problems if the
+ * If-Modified-Since date is derived from the client's clock without correction to the server's clock.
+ * Corrections for different time bases between client and server are at best approximate due to network latency.
+ * The result of a request having both an If-Modified-Since header field and either an If-Match or an
+ * If-Unmodified-Since header fields is undefined by this specification.
+ */
+public final class IfModifiedSince extends HeaderDate {
+
+	/**
+	 * Returns a parsed <code>If-Modified-Since</code> header.
+	 *
+	 * @param value The <code>If-Modified-Since</code> header string.
+	 * @return The parsed <code>If-Modified-Since</code> header, or <jk>null</jk> if the string was null.
+	 */
+	public static IfModifiedSince forString(String value) {
+		if (value == null)
+			return null;
+		return new IfModifiedSince(value);
+	}
+
+	private IfModifiedSince(String value) {
+		super(value);
+	}
+}