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); + } +}
