diff options
author | Matt A. Tobin <mattatobin@localhost.localdomain> | 2018-02-02 04:16:08 -0500 |
---|---|---|
committer | Matt A. Tobin <mattatobin@localhost.localdomain> | 2018-02-02 04:16:08 -0500 |
commit | 5f8de423f190bbb79a62f804151bc24824fa32d8 (patch) | |
tree | 10027f336435511475e392454359edea8e25895d /mobile/android/thirdparty/ch/boye/httpclientandroidlib/impl/cookie | |
parent | 49ee0794b5d912db1f95dce6eb52d781dc210db5 (diff) | |
download | UXP-5f8de423f190bbb79a62f804151bc24824fa32d8.tar UXP-5f8de423f190bbb79a62f804151bc24824fa32d8.tar.gz UXP-5f8de423f190bbb79a62f804151bc24824fa32d8.tar.lz UXP-5f8de423f190bbb79a62f804151bc24824fa32d8.tar.xz UXP-5f8de423f190bbb79a62f804151bc24824fa32d8.zip |
Add m-esr52 at 52.6.0
Diffstat (limited to 'mobile/android/thirdparty/ch/boye/httpclientandroidlib/impl/cookie')
38 files changed, 4398 insertions, 0 deletions
diff --git a/mobile/android/thirdparty/ch/boye/httpclientandroidlib/impl/cookie/AbstractCookieAttributeHandler.java b/mobile/android/thirdparty/ch/boye/httpclientandroidlib/impl/cookie/AbstractCookieAttributeHandler.java new file mode 100644 index 000000000..e9406bab2 --- /dev/null +++ b/mobile/android/thirdparty/ch/boye/httpclientandroidlib/impl/cookie/AbstractCookieAttributeHandler.java @@ -0,0 +1,52 @@ +/* + * ==================================================================== + * 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. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * <http://www.apache.org/>. + * + */ +package ch.boye.httpclientandroidlib.impl.cookie; + +import ch.boye.httpclientandroidlib.annotation.Immutable; +import ch.boye.httpclientandroidlib.cookie.Cookie; +import ch.boye.httpclientandroidlib.cookie.CookieAttributeHandler; +import ch.boye.httpclientandroidlib.cookie.CookieOrigin; +import ch.boye.httpclientandroidlib.cookie.MalformedCookieException; + +/** + * + * @since 4.0 + */ +@Immutable +public abstract class AbstractCookieAttributeHandler implements CookieAttributeHandler { + + public void validate(final Cookie cookie, final CookieOrigin origin) + throws MalformedCookieException { + // Do nothing + } + + public boolean match(final Cookie cookie, final CookieOrigin origin) { + // Always match + return true; + } + +} diff --git a/mobile/android/thirdparty/ch/boye/httpclientandroidlib/impl/cookie/AbstractCookieSpec.java b/mobile/android/thirdparty/ch/boye/httpclientandroidlib/impl/cookie/AbstractCookieSpec.java new file mode 100644 index 000000000..7dc320ef4 --- /dev/null +++ b/mobile/android/thirdparty/ch/boye/httpclientandroidlib/impl/cookie/AbstractCookieSpec.java @@ -0,0 +1,104 @@ +/* + * ==================================================================== + * 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. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * <http://www.apache.org/>. + * + */ + +package ch.boye.httpclientandroidlib.impl.cookie; + +import java.util.Collection; +import java.util.HashMap; +import java.util.Map; + +import ch.boye.httpclientandroidlib.annotation.NotThreadSafe; +import ch.boye.httpclientandroidlib.cookie.CookieAttributeHandler; +import ch.boye.httpclientandroidlib.cookie.CookieSpec; +import ch.boye.httpclientandroidlib.util.Args; + +/** + * Abstract cookie specification which can delegate the job of parsing, + * validation or matching cookie attributes to a number of arbitrary + * {@link CookieAttributeHandler}s. + * + * + * @since 4.0 + */ +@NotThreadSafe // HashMap is not thread-safe +public abstract class AbstractCookieSpec implements CookieSpec { + + /** + * Stores attribute name -> attribute handler mappings + */ + private final Map<String, CookieAttributeHandler> attribHandlerMap; + + /** + * Default constructor + * */ + public AbstractCookieSpec() { + super(); + this.attribHandlerMap = new HashMap<String, CookieAttributeHandler>(10); + } + + public void registerAttribHandler( + final String name, final CookieAttributeHandler handler) { + Args.notNull(name, "Attribute name"); + Args.notNull(handler, "Attribute handler"); + this.attribHandlerMap.put(name, handler); + } + + /** + * Finds an attribute handler {@link CookieAttributeHandler} for the + * given attribute. Returns <tt>null</tt> if no attribute handler is + * found for the specified attribute. + * + * @param name attribute name. e.g. Domain, Path, etc. + * @return an attribute handler or <tt>null</tt> + */ + protected CookieAttributeHandler findAttribHandler(final String name) { + return this.attribHandlerMap.get(name); + } + + /** + * Gets attribute handler {@link CookieAttributeHandler} for the + * given attribute. + * + * @param name attribute name. e.g. Domain, Path, etc. + * @throws IllegalStateException if handler not found for the + * specified attribute. + */ + protected CookieAttributeHandler getAttribHandler(final String name) { + final CookieAttributeHandler handler = findAttribHandler(name); + if (handler == null) { + throw new IllegalStateException("Handler not registered for " + + name + " attribute."); + } else { + return handler; + } + } + + protected Collection<CookieAttributeHandler> getAttribHandlers() { + return this.attribHandlerMap.values(); + } + +} diff --git a/mobile/android/thirdparty/ch/boye/httpclientandroidlib/impl/cookie/BasicClientCookie.java b/mobile/android/thirdparty/ch/boye/httpclientandroidlib/impl/cookie/BasicClientCookie.java new file mode 100644 index 000000000..c826daada --- /dev/null +++ b/mobile/android/thirdparty/ch/boye/httpclientandroidlib/impl/cookie/BasicClientCookie.java @@ -0,0 +1,361 @@ +/* + * ==================================================================== + * 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. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * <http://www.apache.org/>. + * + */ + +package ch.boye.httpclientandroidlib.impl.cookie; + +import java.io.Serializable; +import java.util.Date; +import java.util.HashMap; +import java.util.Locale; +import java.util.Map; + +import ch.boye.httpclientandroidlib.annotation.NotThreadSafe; +import ch.boye.httpclientandroidlib.cookie.ClientCookie; +import ch.boye.httpclientandroidlib.cookie.SetCookie; +import ch.boye.httpclientandroidlib.util.Args; + +/** + * Default implementation of {@link SetCookie}. + * + * @since 4.0 + */ +@NotThreadSafe +public class BasicClientCookie implements SetCookie, ClientCookie, Cloneable, Serializable { + + private static final long serialVersionUID = -3869795591041535538L; + + /** + * Default Constructor taking a name and a value. The value may be null. + * + * @param name The name. + * @param value The value. + */ + public BasicClientCookie(final String name, final String value) { + super(); + Args.notNull(name, "Name"); + this.name = name; + this.attribs = new HashMap<String, String>(); + this.value = value; + } + + /** + * Returns the name. + * + * @return String name The name + */ + public String getName() { + return this.name; + } + + /** + * Returns the value. + * + * @return String value The current value. + */ + public String getValue() { + return this.value; + } + + /** + * Sets the value + * + * @param value + */ + public void setValue(final String value) { + this.value = value; + } + + /** + * Returns the comment describing the purpose of this cookie, or + * <tt>null</tt> if no such comment has been defined. + * + * @return comment + * + * @see #setComment(String) + */ + public String getComment() { + return cookieComment; + } + + /** + * If a user agent (web browser) presents this cookie to a user, the + * cookie's purpose will be described using this comment. + * + * @param comment + * + * @see #getComment() + */ + public void setComment(final String comment) { + cookieComment = comment; + } + + + /** + * Returns null. Cookies prior to RFC2965 do not set this attribute + */ + public String getCommentURL() { + return null; + } + + + /** + * Returns the expiration {@link Date} of the cookie, or <tt>null</tt> + * if none exists. + * <p><strong>Note:</strong> the object returned by this method is + * considered immutable. Changing it (e.g. using setTime()) could result + * in undefined behaviour. Do so at your peril. </p> + * @return Expiration {@link Date}, or <tt>null</tt>. + * + * @see #setExpiryDate(java.util.Date) + * + */ + public Date getExpiryDate() { + return cookieExpiryDate; + } + + /** + * Sets expiration date. + * <p><strong>Note:</strong> the object returned by this method is considered + * immutable. Changing it (e.g. using setTime()) could result in undefined + * behaviour. Do so at your peril.</p> + * + * @param expiryDate the {@link Date} after which this cookie is no longer valid. + * + * @see #getExpiryDate + * + */ + public void setExpiryDate (final Date expiryDate) { + cookieExpiryDate = expiryDate; + } + + + /** + * Returns <tt>false</tt> if the cookie should be discarded at the end + * of the "session"; <tt>true</tt> otherwise. + * + * @return <tt>false</tt> if the cookie should be discarded at the end + * of the "session"; <tt>true</tt> otherwise + */ + public boolean isPersistent() { + return (null != cookieExpiryDate); + } + + + /** + * Returns domain attribute of the cookie. + * + * @return the value of the domain attribute + * + * @see #setDomain(java.lang.String) + */ + public String getDomain() { + return cookieDomain; + } + + /** + * Sets the domain attribute. + * + * @param domain The value of the domain attribute + * + * @see #getDomain + */ + public void setDomain(final String domain) { + if (domain != null) { + cookieDomain = domain.toLowerCase(Locale.ENGLISH); + } else { + cookieDomain = null; + } + } + + + /** + * Returns the path attribute of the cookie + * + * @return The value of the path attribute. + * + * @see #setPath(java.lang.String) + */ + public String getPath() { + return cookiePath; + } + + /** + * Sets the path attribute. + * + * @param path The value of the path attribute + * + * @see #getPath + * + */ + public void setPath(final String path) { + cookiePath = path; + } + + /** + * @return <code>true</code> if this cookie should only be sent over secure connections. + * @see #setSecure(boolean) + */ + public boolean isSecure() { + return isSecure; + } + + /** + * Sets the secure attribute of the cookie. + * <p> + * When <tt>true</tt> the cookie should only be sent + * using a secure protocol (https). This should only be set when + * the cookie's originating server used a secure protocol to set the + * cookie's value. + * + * @param secure The value of the secure attribute + * + * @see #isSecure() + */ + public void setSecure (final boolean secure) { + isSecure = secure; + } + + + /** + * Returns null. Cookies prior to RFC2965 do not set this attribute + */ + public int[] getPorts() { + return null; + } + + + /** + * Returns the version of the cookie specification to which this + * cookie conforms. + * + * @return the version of the cookie. + * + * @see #setVersion(int) + * + */ + public int getVersion() { + return cookieVersion; + } + + /** + * Sets the version of the cookie specification to which this + * cookie conforms. + * + * @param version the version of the cookie. + * + * @see #getVersion + */ + public void setVersion(final int version) { + cookieVersion = version; + } + + /** + * Returns true if this cookie has expired. + * @param date Current time + * + * @return <tt>true</tt> if the cookie has expired. + */ + public boolean isExpired(final Date date) { + Args.notNull(date, "Date"); + return (cookieExpiryDate != null + && cookieExpiryDate.getTime() <= date.getTime()); + } + + public void setAttribute(final String name, final String value) { + this.attribs.put(name, value); + } + + public String getAttribute(final String name) { + return this.attribs.get(name); + } + + public boolean containsAttribute(final String name) { + return this.attribs.get(name) != null; + } + + @Override + public Object clone() throws CloneNotSupportedException { + final BasicClientCookie clone = (BasicClientCookie) super.clone(); + clone.attribs = new HashMap<String, String>(this.attribs); + return clone; + } + + @Override + public String toString() { + final StringBuilder buffer = new StringBuilder(); + buffer.append("[version: "); + buffer.append(Integer.toString(this.cookieVersion)); + buffer.append("]"); + buffer.append("[name: "); + buffer.append(this.name); + buffer.append("]"); + buffer.append("[value: "); + buffer.append(this.value); + buffer.append("]"); + buffer.append("[domain: "); + buffer.append(this.cookieDomain); + buffer.append("]"); + buffer.append("[path: "); + buffer.append(this.cookiePath); + buffer.append("]"); + buffer.append("[expiry: "); + buffer.append(this.cookieExpiryDate); + buffer.append("]"); + return buffer.toString(); + } + + // ----------------------------------------------------- Instance Variables + + /** Cookie name */ + private final String name; + + /** Cookie attributes as specified by the origin server */ + private Map<String, String> attribs; + + /** Cookie value */ + private String value; + + /** Comment attribute. */ + private String cookieComment; + + /** Domain attribute. */ + private String cookieDomain; + + /** Expiration {@link Date}. */ + private Date cookieExpiryDate; + + /** Path attribute. */ + private String cookiePath; + + /** My secure flag. */ + private boolean isSecure; + + /** The version of the cookie specification I was created from. */ + private int cookieVersion; + +} + diff --git a/mobile/android/thirdparty/ch/boye/httpclientandroidlib/impl/cookie/BasicClientCookie2.java b/mobile/android/thirdparty/ch/boye/httpclientandroidlib/impl/cookie/BasicClientCookie2.java new file mode 100644 index 000000000..7ed0f82b6 --- /dev/null +++ b/mobile/android/thirdparty/ch/boye/httpclientandroidlib/impl/cookie/BasicClientCookie2.java @@ -0,0 +1,101 @@ +/* + * ==================================================================== + * 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. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * <http://www.apache.org/>. + * + */ + +package ch.boye.httpclientandroidlib.impl.cookie; + +import java.util.Date; + +import ch.boye.httpclientandroidlib.annotation.NotThreadSafe; +import ch.boye.httpclientandroidlib.cookie.SetCookie2; + +/** + * Default implementation of {@link SetCookie2}. + * + * @since 4.0 + */ +@NotThreadSafe +public class BasicClientCookie2 extends BasicClientCookie implements SetCookie2 { + + private static final long serialVersionUID = -7744598295706617057L; + + private String commentURL; + private int[] ports; + private boolean discard; + + /** + * Default Constructor taking a name and a value. The value may be null. + * + * @param name The name. + * @param value The value. + */ + public BasicClientCookie2(final String name, final String value) { + super(name, value); + } + + @Override + public int[] getPorts() { + return this.ports; + } + + public void setPorts(final int[] ports) { + this.ports = ports; + } + + @Override + public String getCommentURL() { + return this.commentURL; + } + + public void setCommentURL(final String commentURL) { + this.commentURL = commentURL; + } + + public void setDiscard(final boolean discard) { + this.discard = discard; + } + + @Override + public boolean isPersistent() { + return !this.discard && super.isPersistent(); + } + + @Override + public boolean isExpired(final Date date) { + return this.discard || super.isExpired(date); + } + + @Override + public Object clone() throws CloneNotSupportedException { + final BasicClientCookie2 clone = (BasicClientCookie2) super.clone(); + if (this.ports != null) { + clone.ports = this.ports.clone(); + } + return clone; + } + +} + diff --git a/mobile/android/thirdparty/ch/boye/httpclientandroidlib/impl/cookie/BasicCommentHandler.java b/mobile/android/thirdparty/ch/boye/httpclientandroidlib/impl/cookie/BasicCommentHandler.java new file mode 100644 index 000000000..69d65b961 --- /dev/null +++ b/mobile/android/thirdparty/ch/boye/httpclientandroidlib/impl/cookie/BasicCommentHandler.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. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * <http://www.apache.org/>. + * + */ +package ch.boye.httpclientandroidlib.impl.cookie; + +import ch.boye.httpclientandroidlib.annotation.Immutable; +import ch.boye.httpclientandroidlib.cookie.MalformedCookieException; +import ch.boye.httpclientandroidlib.cookie.SetCookie; +import ch.boye.httpclientandroidlib.util.Args; + +/** + * + * @since 4.0 + */ +@Immutable +public class BasicCommentHandler extends AbstractCookieAttributeHandler { + + public BasicCommentHandler() { + super(); + } + + public void parse(final SetCookie cookie, final String value) + throws MalformedCookieException { + Args.notNull(cookie, "Cookie"); + cookie.setComment(value); + } + +} diff --git a/mobile/android/thirdparty/ch/boye/httpclientandroidlib/impl/cookie/BasicDomainHandler.java b/mobile/android/thirdparty/ch/boye/httpclientandroidlib/impl/cookie/BasicDomainHandler.java new file mode 100644 index 000000000..bad00ec48 --- /dev/null +++ b/mobile/android/thirdparty/ch/boye/httpclientandroidlib/impl/cookie/BasicDomainHandler.java @@ -0,0 +1,116 @@ +/* + * ==================================================================== + * 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. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * <http://www.apache.org/>. + * + */ +package ch.boye.httpclientandroidlib.impl.cookie; + +import ch.boye.httpclientandroidlib.annotation.Immutable; +import ch.boye.httpclientandroidlib.cookie.Cookie; +import ch.boye.httpclientandroidlib.cookie.CookieAttributeHandler; +import ch.boye.httpclientandroidlib.cookie.CookieOrigin; +import ch.boye.httpclientandroidlib.cookie.CookieRestrictionViolationException; +import ch.boye.httpclientandroidlib.cookie.MalformedCookieException; +import ch.boye.httpclientandroidlib.cookie.SetCookie; +import ch.boye.httpclientandroidlib.util.Args; + +/** + * + * @since 4.0 + */ +@Immutable +public class BasicDomainHandler implements CookieAttributeHandler { + + public BasicDomainHandler() { + super(); + } + + public void parse(final SetCookie cookie, final String value) + throws MalformedCookieException { + Args.notNull(cookie, "Cookie"); + if (value == null) { + throw new MalformedCookieException("Missing value for domain attribute"); + } + if (value.trim().length() == 0) { + throw new MalformedCookieException("Blank value for domain attribute"); + } + cookie.setDomain(value); + } + + public void validate(final Cookie cookie, final CookieOrigin origin) + throws MalformedCookieException { + Args.notNull(cookie, "Cookie"); + Args.notNull(origin, "Cookie origin"); + // Validate the cookies domain attribute. NOTE: Domains without + // any dots are allowed to support hosts on private LANs that don't + // have DNS names. Since they have no dots, to domain-match the + // request-host and domain must be identical for the cookie to sent + // back to the origin-server. + final String host = origin.getHost(); + String domain = cookie.getDomain(); + if (domain == null) { + throw new CookieRestrictionViolationException("Cookie domain may not be null"); + } + if (host.contains(".")) { + // Not required to have at least two dots. RFC 2965. + // A Set-Cookie2 with Domain=ajax.com will be accepted. + + // domain must match host + if (!host.endsWith(domain)) { + if (domain.startsWith(".")) { + domain = domain.substring(1, domain.length()); + } + if (!host.equals(domain)) { + throw new CookieRestrictionViolationException( + "Illegal domain attribute \"" + domain + + "\". Domain of origin: \"" + host + "\""); + } + } + } else { + if (!host.equals(domain)) { + throw new CookieRestrictionViolationException( + "Illegal domain attribute \"" + domain + + "\". Domain of origin: \"" + host + "\""); + } + } + } + + public boolean match(final Cookie cookie, final CookieOrigin origin) { + Args.notNull(cookie, "Cookie"); + Args.notNull(origin, "Cookie origin"); + final String host = origin.getHost(); + String domain = cookie.getDomain(); + if (domain == null) { + return false; + } + if (host.equals(domain)) { + return true; + } + if (!domain.startsWith(".")) { + domain = '.' + domain; + } + return host.endsWith(domain) || host.equals(domain.substring(1)); + } + +} diff --git a/mobile/android/thirdparty/ch/boye/httpclientandroidlib/impl/cookie/BasicExpiresHandler.java b/mobile/android/thirdparty/ch/boye/httpclientandroidlib/impl/cookie/BasicExpiresHandler.java new file mode 100644 index 000000000..9b9dee5b2 --- /dev/null +++ b/mobile/android/thirdparty/ch/boye/httpclientandroidlib/impl/cookie/BasicExpiresHandler.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. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * <http://www.apache.org/>. + * + */ +package ch.boye.httpclientandroidlib.impl.cookie; + +import java.util.Date; + +import ch.boye.httpclientandroidlib.annotation.Immutable; +import ch.boye.httpclientandroidlib.client.utils.DateUtils; +import ch.boye.httpclientandroidlib.cookie.MalformedCookieException; +import ch.boye.httpclientandroidlib.cookie.SetCookie; +import ch.boye.httpclientandroidlib.util.Args; + +/** + * + * @since 4.0 + */ +@Immutable +public class BasicExpiresHandler extends AbstractCookieAttributeHandler { + + /** Valid date patterns */ + private final String[] datepatterns; + + public BasicExpiresHandler(final String[] datepatterns) { + Args.notNull(datepatterns, "Array of date patterns"); + this.datepatterns = datepatterns; + } + + public void parse(final SetCookie cookie, final String value) + throws MalformedCookieException { + Args.notNull(cookie, "Cookie"); + if (value == null) { + throw new MalformedCookieException("Missing value for expires attribute"); + } + final Date expiry = DateUtils.parseDate(value, this.datepatterns); + if (expiry == null) { + throw new MalformedCookieException("Unable to parse expires attribute: " + + value); + } + cookie.setExpiryDate(expiry); + } + +} diff --git a/mobile/android/thirdparty/ch/boye/httpclientandroidlib/impl/cookie/BasicMaxAgeHandler.java b/mobile/android/thirdparty/ch/boye/httpclientandroidlib/impl/cookie/BasicMaxAgeHandler.java new file mode 100644 index 000000000..750361b22 --- /dev/null +++ b/mobile/android/thirdparty/ch/boye/httpclientandroidlib/impl/cookie/BasicMaxAgeHandler.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. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * <http://www.apache.org/>. + * + */ +package ch.boye.httpclientandroidlib.impl.cookie; + +import java.util.Date; + +import ch.boye.httpclientandroidlib.annotation.Immutable; +import ch.boye.httpclientandroidlib.cookie.MalformedCookieException; +import ch.boye.httpclientandroidlib.cookie.SetCookie; +import ch.boye.httpclientandroidlib.util.Args; + +/** + * + * @since 4.0 + */ +@Immutable +public class BasicMaxAgeHandler extends AbstractCookieAttributeHandler { + + public BasicMaxAgeHandler() { + super(); + } + + public void parse(final SetCookie cookie, final String value) + throws MalformedCookieException { + Args.notNull(cookie, "Cookie"); + if (value == null) { + throw new MalformedCookieException("Missing value for max-age attribute"); + } + final int age; + try { + age = Integer.parseInt(value); + } catch (final NumberFormatException e) { + throw new MalformedCookieException ("Invalid max-age attribute: " + + value); + } + if (age < 0) { + throw new MalformedCookieException ("Negative max-age attribute: " + + value); + } + cookie.setExpiryDate(new Date(System.currentTimeMillis() + age * 1000L)); + } + +} diff --git a/mobile/android/thirdparty/ch/boye/httpclientandroidlib/impl/cookie/BasicPathHandler.java b/mobile/android/thirdparty/ch/boye/httpclientandroidlib/impl/cookie/BasicPathHandler.java new file mode 100644 index 000000000..e73657148 --- /dev/null +++ b/mobile/android/thirdparty/ch/boye/httpclientandroidlib/impl/cookie/BasicPathHandler.java @@ -0,0 +1,87 @@ +/* + * ==================================================================== + * 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. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * <http://www.apache.org/>. + * + */ +package ch.boye.httpclientandroidlib.impl.cookie; + +import ch.boye.httpclientandroidlib.annotation.Immutable; +import ch.boye.httpclientandroidlib.cookie.Cookie; +import ch.boye.httpclientandroidlib.cookie.CookieAttributeHandler; +import ch.boye.httpclientandroidlib.cookie.CookieOrigin; +import ch.boye.httpclientandroidlib.cookie.CookieRestrictionViolationException; +import ch.boye.httpclientandroidlib.cookie.MalformedCookieException; +import ch.boye.httpclientandroidlib.cookie.SetCookie; +import ch.boye.httpclientandroidlib.util.Args; +import ch.boye.httpclientandroidlib.util.TextUtils; + +/** + * + * @since 4.0 + */ +@Immutable +public class BasicPathHandler implements CookieAttributeHandler { + + public BasicPathHandler() { + super(); + } + + public void parse( + final SetCookie cookie, final String value) throws MalformedCookieException { + Args.notNull(cookie, "Cookie"); + cookie.setPath(!TextUtils.isBlank(value) ? value : "/"); + } + + public void validate(final Cookie cookie, final CookieOrigin origin) + throws MalformedCookieException { + if (!match(cookie, origin)) { + throw new CookieRestrictionViolationException( + "Illegal path attribute \"" + cookie.getPath() + + "\". Path of origin: \"" + origin.getPath() + "\""); + } + } + + public boolean match(final Cookie cookie, final CookieOrigin origin) { + Args.notNull(cookie, "Cookie"); + Args.notNull(origin, "Cookie origin"); + final String targetpath = origin.getPath(); + String topmostPath = cookie.getPath(); + if (topmostPath == null) { + topmostPath = "/"; + } + if (topmostPath.length() > 1 && topmostPath.endsWith("/")) { + topmostPath = topmostPath.substring(0, topmostPath.length() - 1); + } + boolean match = targetpath.startsWith (topmostPath); + // if there is a match and these values are not exactly the same we have + // to make sure we're not matcing "/foobar" and "/foo" + if (match && targetpath.length() != topmostPath.length()) { + if (!topmostPath.endsWith("/")) { + match = (targetpath.charAt(topmostPath.length()) == '/'); + } + } + return match; + } + +} diff --git a/mobile/android/thirdparty/ch/boye/httpclientandroidlib/impl/cookie/BasicSecureHandler.java b/mobile/android/thirdparty/ch/boye/httpclientandroidlib/impl/cookie/BasicSecureHandler.java new file mode 100644 index 000000000..939741fc3 --- /dev/null +++ b/mobile/android/thirdparty/ch/boye/httpclientandroidlib/impl/cookie/BasicSecureHandler.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. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * <http://www.apache.org/>. + * + */ +package ch.boye.httpclientandroidlib.impl.cookie; + +import ch.boye.httpclientandroidlib.annotation.Immutable; +import ch.boye.httpclientandroidlib.cookie.Cookie; +import ch.boye.httpclientandroidlib.cookie.CookieOrigin; +import ch.boye.httpclientandroidlib.cookie.MalformedCookieException; +import ch.boye.httpclientandroidlib.cookie.SetCookie; +import ch.boye.httpclientandroidlib.util.Args; + +/** + * + * @since 4.0 + */ +@Immutable +public class BasicSecureHandler extends AbstractCookieAttributeHandler { + + public BasicSecureHandler() { + super(); + } + + public void parse(final SetCookie cookie, final String value) + throws MalformedCookieException { + Args.notNull(cookie, "Cookie"); + cookie.setSecure(true); + } + + @Override + public boolean match(final Cookie cookie, final CookieOrigin origin) { + Args.notNull(cookie, "Cookie"); + Args.notNull(origin, "Cookie origin"); + return !cookie.isSecure() || origin.isSecure(); + } + +} diff --git a/mobile/android/thirdparty/ch/boye/httpclientandroidlib/impl/cookie/BestMatchSpec.java b/mobile/android/thirdparty/ch/boye/httpclientandroidlib/impl/cookie/BestMatchSpec.java new file mode 100644 index 000000000..bdb06090d --- /dev/null +++ b/mobile/android/thirdparty/ch/boye/httpclientandroidlib/impl/cookie/BestMatchSpec.java @@ -0,0 +1,207 @@ +/* + * ==================================================================== + * 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. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * <http://www.apache.org/>. + * + */ + +package ch.boye.httpclientandroidlib.impl.cookie; + +import java.util.List; + +import ch.boye.httpclientandroidlib.FormattedHeader; +import ch.boye.httpclientandroidlib.Header; +import ch.boye.httpclientandroidlib.HeaderElement; +import ch.boye.httpclientandroidlib.annotation.NotThreadSafe; +import ch.boye.httpclientandroidlib.cookie.Cookie; +import ch.boye.httpclientandroidlib.cookie.CookieOrigin; +import ch.boye.httpclientandroidlib.cookie.CookieSpec; +import ch.boye.httpclientandroidlib.cookie.MalformedCookieException; +import ch.boye.httpclientandroidlib.cookie.SM; +import ch.boye.httpclientandroidlib.cookie.SetCookie2; +import ch.boye.httpclientandroidlib.message.ParserCursor; +import ch.boye.httpclientandroidlib.util.Args; +import ch.boye.httpclientandroidlib.util.CharArrayBuffer; + +/** + * 'Meta' cookie specification that picks up a cookie policy based on + * the format of cookies sent with the HTTP response. + * + * @since 4.0 + */ +@NotThreadSafe // CookieSpec fields are @NotThreadSafe +public class BestMatchSpec implements CookieSpec { + + private final String[] datepatterns; + private final boolean oneHeader; + + // Cached values of CookieSpec instances + private RFC2965Spec strict; // @NotThreadSafe + private RFC2109Spec obsoleteStrict; // @NotThreadSafe + private BrowserCompatSpec compat; // @NotThreadSafe + + public BestMatchSpec(final String[] datepatterns, final boolean oneHeader) { + super(); + this.datepatterns = datepatterns == null ? null : datepatterns.clone(); + this.oneHeader = oneHeader; + } + + public BestMatchSpec() { + this(null, false); + } + + private RFC2965Spec getStrict() { + if (this.strict == null) { + this.strict = new RFC2965Spec(this.datepatterns, this.oneHeader); + } + return strict; + } + + private RFC2109Spec getObsoleteStrict() { + if (this.obsoleteStrict == null) { + this.obsoleteStrict = new RFC2109Spec(this.datepatterns, this.oneHeader); + } + return obsoleteStrict; + } + + private BrowserCompatSpec getCompat() { + if (this.compat == null) { + this.compat = new BrowserCompatSpec(this.datepatterns); + } + return compat; + } + + public List<Cookie> parse( + final Header header, + final CookieOrigin origin) throws MalformedCookieException { + Args.notNull(header, "Header"); + Args.notNull(origin, "Cookie origin"); + HeaderElement[] helems = header.getElements(); + boolean versioned = false; + boolean netscape = false; + for (final HeaderElement helem: helems) { + if (helem.getParameterByName("version") != null) { + versioned = true; + } + if (helem.getParameterByName("expires") != null) { + netscape = true; + } + } + if (netscape || !versioned) { + // Need to parse the header again, because Netscape style cookies do not correctly + // support multiple header elements (comma cannot be treated as an element separator) + final NetscapeDraftHeaderParser parser = NetscapeDraftHeaderParser.DEFAULT; + final CharArrayBuffer buffer; + final ParserCursor cursor; + if (header instanceof FormattedHeader) { + buffer = ((FormattedHeader) header).getBuffer(); + cursor = new ParserCursor( + ((FormattedHeader) header).getValuePos(), + buffer.length()); + } else { + final String s = header.getValue(); + if (s == null) { + throw new MalformedCookieException("Header value is null"); + } + buffer = new CharArrayBuffer(s.length()); + buffer.append(s); + cursor = new ParserCursor(0, buffer.length()); + } + helems = new HeaderElement[] { parser.parseHeader(buffer, cursor) }; + return getCompat().parse(helems, origin); + } else { + if (SM.SET_COOKIE2.equals(header.getName())) { + return getStrict().parse(helems, origin); + } else { + return getObsoleteStrict().parse(helems, origin); + } + } + } + + public void validate( + final Cookie cookie, + final CookieOrigin origin) throws MalformedCookieException { + Args.notNull(cookie, "Cookie"); + Args.notNull(origin, "Cookie origin"); + if (cookie.getVersion() > 0) { + if (cookie instanceof SetCookie2) { + getStrict().validate(cookie, origin); + } else { + getObsoleteStrict().validate(cookie, origin); + } + } else { + getCompat().validate(cookie, origin); + } + } + + public boolean match(final Cookie cookie, final CookieOrigin origin) { + Args.notNull(cookie, "Cookie"); + Args.notNull(origin, "Cookie origin"); + if (cookie.getVersion() > 0) { + if (cookie instanceof SetCookie2) { + return getStrict().match(cookie, origin); + } else { + return getObsoleteStrict().match(cookie, origin); + } + } else { + return getCompat().match(cookie, origin); + } + } + + public List<Header> formatCookies(final List<Cookie> cookies) { + Args.notNull(cookies, "List of cookies"); + int version = Integer.MAX_VALUE; + boolean isSetCookie2 = true; + for (final Cookie cookie: cookies) { + if (!(cookie instanceof SetCookie2)) { + isSetCookie2 = false; + } + if (cookie.getVersion() < version) { + version = cookie.getVersion(); + } + } + if (version > 0) { + if (isSetCookie2) { + return getStrict().formatCookies(cookies); + } else { + return getObsoleteStrict().formatCookies(cookies); + } + } else { + return getCompat().formatCookies(cookies); + } + } + + public int getVersion() { + return getStrict().getVersion(); + } + + public Header getVersionHeader() { + return getStrict().getVersionHeader(); + } + + @Override + public String toString() { + return "best-match"; + } + +} diff --git a/mobile/android/thirdparty/ch/boye/httpclientandroidlib/impl/cookie/BestMatchSpecFactory.java b/mobile/android/thirdparty/ch/boye/httpclientandroidlib/impl/cookie/BestMatchSpecFactory.java new file mode 100644 index 000000000..c20e4bcd1 --- /dev/null +++ b/mobile/android/thirdparty/ch/boye/httpclientandroidlib/impl/cookie/BestMatchSpecFactory.java @@ -0,0 +1,86 @@ +/* + * ==================================================================== + * 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. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * <http://www.apache.org/>. + * + */ + +package ch.boye.httpclientandroidlib.impl.cookie; + +import java.util.Collection; + +import ch.boye.httpclientandroidlib.annotation.Immutable; +import ch.boye.httpclientandroidlib.cookie.CookieSpec; +import ch.boye.httpclientandroidlib.cookie.CookieSpecFactory; +import ch.boye.httpclientandroidlib.cookie.CookieSpecProvider; +import ch.boye.httpclientandroidlib.cookie.params.CookieSpecPNames; +import ch.boye.httpclientandroidlib.params.HttpParams; +import ch.boye.httpclientandroidlib.protocol.HttpContext; + +/** + * {@link CookieSpecProvider} implementation that creates and initializes + * {@link BestMatchSpec} instances. + * + * @since 4.0 + */ +@Immutable +@SuppressWarnings("deprecation") +public class BestMatchSpecFactory implements CookieSpecFactory, CookieSpecProvider { + + private final String[] datepatterns; + private final boolean oneHeader; + + public BestMatchSpecFactory(final String[] datepatterns, final boolean oneHeader) { + super(); + this.datepatterns = datepatterns; + this.oneHeader = oneHeader; + } + + public BestMatchSpecFactory() { + this(null, false); + } + + public CookieSpec newInstance(final HttpParams params) { + if (params != null) { + + String[] patterns = null; + final Collection<?> param = (Collection<?>) params.getParameter( + CookieSpecPNames.DATE_PATTERNS); + if (param != null) { + patterns = new String[param.size()]; + patterns = param.toArray(patterns); + } + final boolean singleHeader = params.getBooleanParameter( + CookieSpecPNames.SINGLE_COOKIE_HEADER, false); + + return new BestMatchSpec(patterns, singleHeader); + } else { + return new BestMatchSpec(); + } + } + + public CookieSpec create(final HttpContext context) { + return new BestMatchSpec(this.datepatterns, this.oneHeader); + } + +} diff --git a/mobile/android/thirdparty/ch/boye/httpclientandroidlib/impl/cookie/BrowserCompatSpec.java b/mobile/android/thirdparty/ch/boye/httpclientandroidlib/impl/cookie/BrowserCompatSpec.java new file mode 100644 index 000000000..6caa71987 --- /dev/null +++ b/mobile/android/thirdparty/ch/boye/httpclientandroidlib/impl/cookie/BrowserCompatSpec.java @@ -0,0 +1,219 @@ +/* + * ==================================================================== + * 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. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * <http://www.apache.org/>. + * + */ + +package ch.boye.httpclientandroidlib.impl.cookie; + +import java.util.ArrayList; +import java.util.List; + +import ch.boye.httpclientandroidlib.FormattedHeader; +import ch.boye.httpclientandroidlib.Header; +import ch.boye.httpclientandroidlib.HeaderElement; +import ch.boye.httpclientandroidlib.annotation.NotThreadSafe; +import ch.boye.httpclientandroidlib.client.utils.DateUtils; +import ch.boye.httpclientandroidlib.cookie.ClientCookie; +import ch.boye.httpclientandroidlib.cookie.Cookie; +import ch.boye.httpclientandroidlib.cookie.CookieOrigin; +import ch.boye.httpclientandroidlib.cookie.MalformedCookieException; +import ch.boye.httpclientandroidlib.cookie.SM; +import ch.boye.httpclientandroidlib.message.BasicHeaderElement; +import ch.boye.httpclientandroidlib.message.BasicHeaderValueFormatter; +import ch.boye.httpclientandroidlib.message.BufferedHeader; +import ch.boye.httpclientandroidlib.message.ParserCursor; +import ch.boye.httpclientandroidlib.util.Args; +import ch.boye.httpclientandroidlib.util.CharArrayBuffer; + + +/** + * Cookie specification that strives to closely mimic (mis)behavior of + * common web browser applications such as Microsoft Internet Explorer + * and Mozilla FireFox. + * + * + * @since 4.0 + */ +@NotThreadSafe // superclass is @NotThreadSafe +public class BrowserCompatSpec extends CookieSpecBase { + + + private static final String[] DEFAULT_DATE_PATTERNS = new String[] { + DateUtils.PATTERN_RFC1123, + DateUtils.PATTERN_RFC1036, + DateUtils.PATTERN_ASCTIME, + "EEE, dd-MMM-yyyy HH:mm:ss z", + "EEE, dd-MMM-yyyy HH-mm-ss z", + "EEE, dd MMM yy HH:mm:ss z", + "EEE dd-MMM-yyyy HH:mm:ss z", + "EEE dd MMM yyyy HH:mm:ss z", + "EEE dd-MMM-yyyy HH-mm-ss z", + "EEE dd-MMM-yy HH:mm:ss z", + "EEE dd MMM yy HH:mm:ss z", + "EEE,dd-MMM-yy HH:mm:ss z", + "EEE,dd-MMM-yyyy HH:mm:ss z", + "EEE, dd-MM-yyyy HH:mm:ss z", + }; + + private final String[] datepatterns; + + /** Default constructor */ + public BrowserCompatSpec(final String[] datepatterns, final BrowserCompatSpecFactory.SecurityLevel securityLevel) { + super(); + if (datepatterns != null) { + this.datepatterns = datepatterns.clone(); + } else { + this.datepatterns = DEFAULT_DATE_PATTERNS; + } + switch (securityLevel) { + case SECURITYLEVEL_DEFAULT: + registerAttribHandler(ClientCookie.PATH_ATTR, new BasicPathHandler()); + break; + case SECURITYLEVEL_IE_MEDIUM: + registerAttribHandler(ClientCookie.PATH_ATTR, new BasicPathHandler() { + @Override + public void validate(final Cookie cookie, final CookieOrigin origin) throws MalformedCookieException { + // No validation + } + } + ); + break; + default: + throw new RuntimeException("Unknown security level"); + } + + registerAttribHandler(ClientCookie.DOMAIN_ATTR, new BasicDomainHandler()); + registerAttribHandler(ClientCookie.MAX_AGE_ATTR, new BasicMaxAgeHandler()); + registerAttribHandler(ClientCookie.SECURE_ATTR, new BasicSecureHandler()); + registerAttribHandler(ClientCookie.COMMENT_ATTR, new BasicCommentHandler()); + registerAttribHandler(ClientCookie.EXPIRES_ATTR, new BasicExpiresHandler( + this.datepatterns)); + registerAttribHandler(ClientCookie.VERSION_ATTR, new BrowserCompatVersionAttributeHandler()); + } + + /** Default constructor */ + public BrowserCompatSpec(final String[] datepatterns) { + this(datepatterns, BrowserCompatSpecFactory.SecurityLevel.SECURITYLEVEL_DEFAULT); + } + + /** Default constructor */ + public BrowserCompatSpec() { + this(null, BrowserCompatSpecFactory.SecurityLevel.SECURITYLEVEL_DEFAULT); + } + + public List<Cookie> parse(final Header header, final CookieOrigin origin) + throws MalformedCookieException { + Args.notNull(header, "Header"); + Args.notNull(origin, "Cookie origin"); + final String headername = header.getName(); + if (!headername.equalsIgnoreCase(SM.SET_COOKIE)) { + throw new MalformedCookieException("Unrecognized cookie header '" + + header.toString() + "'"); + } + HeaderElement[] helems = header.getElements(); + boolean versioned = false; + boolean netscape = false; + for (final HeaderElement helem: helems) { + if (helem.getParameterByName("version") != null) { + versioned = true; + } + if (helem.getParameterByName("expires") != null) { + netscape = true; + } + } + if (netscape || !versioned) { + // Need to parse the header again, because Netscape style cookies do not correctly + // support multiple header elements (comma cannot be treated as an element separator) + final NetscapeDraftHeaderParser parser = NetscapeDraftHeaderParser.DEFAULT; + final CharArrayBuffer buffer; + final ParserCursor cursor; + if (header instanceof FormattedHeader) { + buffer = ((FormattedHeader) header).getBuffer(); + cursor = new ParserCursor( + ((FormattedHeader) header).getValuePos(), + buffer.length()); + } else { + final String s = header.getValue(); + if (s == null) { + throw new MalformedCookieException("Header value is null"); + } + buffer = new CharArrayBuffer(s.length()); + buffer.append(s); + cursor = new ParserCursor(0, buffer.length()); + } + helems = new HeaderElement[] { parser.parseHeader(buffer, cursor) }; + } + return parse(helems, origin); + } + + private static boolean isQuoteEnclosed(final String s) { + return s != null && s.startsWith("\"") && s.endsWith("\""); + } + + public List<Header> formatCookies(final List<Cookie> cookies) { + Args.notEmpty(cookies, "List of cookies"); + final CharArrayBuffer buffer = new CharArrayBuffer(20 * cookies.size()); + buffer.append(SM.COOKIE); + buffer.append(": "); + for (int i = 0; i < cookies.size(); i++) { + final Cookie cookie = cookies.get(i); + if (i > 0) { + buffer.append("; "); + } + final String cookieName = cookie.getName(); + final String cookieValue = cookie.getValue(); + if (cookie.getVersion() > 0 && !isQuoteEnclosed(cookieValue)) { + BasicHeaderValueFormatter.INSTANCE.formatHeaderElement( + buffer, + new BasicHeaderElement(cookieName, cookieValue), + false); + } else { + // Netscape style cookies do not support quoted values + buffer.append(cookieName); + buffer.append("="); + if (cookieValue != null) { + buffer.append(cookieValue); + } + } + } + final List<Header> headers = new ArrayList<Header>(1); + headers.add(new BufferedHeader(buffer)); + return headers; + } + + public int getVersion() { + return 0; + } + + public Header getVersionHeader() { + return null; + } + + @Override + public String toString() { + return "compatibility"; + } + +} diff --git a/mobile/android/thirdparty/ch/boye/httpclientandroidlib/impl/cookie/BrowserCompatSpecFactory.java b/mobile/android/thirdparty/ch/boye/httpclientandroidlib/impl/cookie/BrowserCompatSpecFactory.java new file mode 100644 index 000000000..f6239b4f3 --- /dev/null +++ b/mobile/android/thirdparty/ch/boye/httpclientandroidlib/impl/cookie/BrowserCompatSpecFactory.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. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * <http://www.apache.org/>. + * + */ + +package ch.boye.httpclientandroidlib.impl.cookie; + +import java.util.Collection; + +import ch.boye.httpclientandroidlib.annotation.Immutable; +import ch.boye.httpclientandroidlib.cookie.CookieSpec; +import ch.boye.httpclientandroidlib.cookie.CookieSpecFactory; +import ch.boye.httpclientandroidlib.cookie.CookieSpecProvider; +import ch.boye.httpclientandroidlib.cookie.params.CookieSpecPNames; +import ch.boye.httpclientandroidlib.params.HttpParams; +import ch.boye.httpclientandroidlib.protocol.HttpContext; + +/** + * {@link CookieSpecProvider} implementation that creates and initializes + * {@link BrowserCompatSpec} instances. + * + * @since 4.0 + */ +@Immutable +@SuppressWarnings("deprecation") +public class BrowserCompatSpecFactory implements CookieSpecFactory, CookieSpecProvider { + + public enum SecurityLevel { + SECURITYLEVEL_DEFAULT, + SECURITYLEVEL_IE_MEDIUM + } + + private final String[] datepatterns; + private final SecurityLevel securityLevel; + + public BrowserCompatSpecFactory(final String[] datepatterns, final SecurityLevel securityLevel) { + super(); + this.datepatterns = datepatterns; + this.securityLevel = securityLevel; + } + + public BrowserCompatSpecFactory(final String[] datepatterns) { + this(null, SecurityLevel.SECURITYLEVEL_DEFAULT); + } + + public BrowserCompatSpecFactory() { + this(null, SecurityLevel.SECURITYLEVEL_DEFAULT); + } + + public CookieSpec newInstance(final HttpParams params) { + if (params != null) { + + String[] patterns = null; + final Collection<?> param = (Collection<?>) params.getParameter( + CookieSpecPNames.DATE_PATTERNS); + if (param != null) { + patterns = new String[param.size()]; + patterns = param.toArray(patterns); + } + return new BrowserCompatSpec(patterns, securityLevel); + } else { + return new BrowserCompatSpec(null, securityLevel); + } + } + + public CookieSpec create(final HttpContext context) { + return new BrowserCompatSpec(this.datepatterns); + } + +} diff --git a/mobile/android/thirdparty/ch/boye/httpclientandroidlib/impl/cookie/BrowserCompatVersionAttributeHandler.java b/mobile/android/thirdparty/ch/boye/httpclientandroidlib/impl/cookie/BrowserCompatVersionAttributeHandler.java new file mode 100644 index 000000000..210fac962 --- /dev/null +++ b/mobile/android/thirdparty/ch/boye/httpclientandroidlib/impl/cookie/BrowserCompatVersionAttributeHandler.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. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * <http://www.apache.org/>. + * + */ + +package ch.boye.httpclientandroidlib.impl.cookie; + +import ch.boye.httpclientandroidlib.annotation.Immutable; +import ch.boye.httpclientandroidlib.cookie.MalformedCookieException; +import ch.boye.httpclientandroidlib.cookie.SetCookie; +import ch.boye.httpclientandroidlib.util.Args; + +/** + * <tt>"Version"</tt> cookie attribute handler for BrowserCompat cookie spec. + * + * @since 4.3 + */ +@Immutable +public class BrowserCompatVersionAttributeHandler extends + AbstractCookieAttributeHandler { + + public BrowserCompatVersionAttributeHandler() { + super(); + } + + /** + * Parse cookie version attribute. + */ + public void parse(final SetCookie cookie, final String value) + throws MalformedCookieException { + Args.notNull(cookie, "Cookie"); + if (value == null) { + throw new MalformedCookieException("Missing value for version attribute"); + } + int version = 0; + try { + version = Integer.parseInt(value); + } catch (final NumberFormatException e) { + // Just ignore invalid versions + } + cookie.setVersion(version); + } + +} diff --git a/mobile/android/thirdparty/ch/boye/httpclientandroidlib/impl/cookie/CookieSpecBase.java b/mobile/android/thirdparty/ch/boye/httpclientandroidlib/impl/cookie/CookieSpecBase.java new file mode 100644 index 000000000..e59c3686e --- /dev/null +++ b/mobile/android/thirdparty/ch/boye/httpclientandroidlib/impl/cookie/CookieSpecBase.java @@ -0,0 +1,121 @@ +/* + * ==================================================================== + * 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. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * <http://www.apache.org/>. + * + */ + +package ch.boye.httpclientandroidlib.impl.cookie; + +import java.util.ArrayList; +import java.util.List; +import java.util.Locale; + +import ch.boye.httpclientandroidlib.HeaderElement; +import ch.boye.httpclientandroidlib.NameValuePair; +import ch.boye.httpclientandroidlib.annotation.NotThreadSafe; +import ch.boye.httpclientandroidlib.cookie.Cookie; +import ch.boye.httpclientandroidlib.cookie.CookieAttributeHandler; +import ch.boye.httpclientandroidlib.cookie.CookieOrigin; +import ch.boye.httpclientandroidlib.cookie.MalformedCookieException; +import ch.boye.httpclientandroidlib.util.Args; + +/** + * Cookie management functions shared by all specification. + * + * + * @since 4.0 + */ +@NotThreadSafe // AbstractCookieSpec is not thread-safe +public abstract class CookieSpecBase extends AbstractCookieSpec { + + protected static String getDefaultPath(final CookieOrigin origin) { + String defaultPath = origin.getPath(); + int lastSlashIndex = defaultPath.lastIndexOf('/'); + if (lastSlashIndex >= 0) { + if (lastSlashIndex == 0) { + //Do not remove the very first slash + lastSlashIndex = 1; + } + defaultPath = defaultPath.substring(0, lastSlashIndex); + } + return defaultPath; + } + + protected static String getDefaultDomain(final CookieOrigin origin) { + return origin.getHost(); + } + + protected List<Cookie> parse(final HeaderElement[] elems, final CookieOrigin origin) + throws MalformedCookieException { + final List<Cookie> cookies = new ArrayList<Cookie>(elems.length); + for (final HeaderElement headerelement : elems) { + final String name = headerelement.getName(); + final String value = headerelement.getValue(); + if (name == null || name.length() == 0) { + throw new MalformedCookieException("Cookie name may not be empty"); + } + + final BasicClientCookie cookie = new BasicClientCookie(name, value); + cookie.setPath(getDefaultPath(origin)); + cookie.setDomain(getDefaultDomain(origin)); + + // cycle through the parameters + final NameValuePair[] attribs = headerelement.getParameters(); + for (int j = attribs.length - 1; j >= 0; j--) { + final NameValuePair attrib = attribs[j]; + final String s = attrib.getName().toLowerCase(Locale.ENGLISH); + + cookie.setAttribute(s, attrib.getValue()); + + final CookieAttributeHandler handler = findAttribHandler(s); + if (handler != null) { + handler.parse(cookie, attrib.getValue()); + } + } + cookies.add(cookie); + } + return cookies; + } + + public void validate(final Cookie cookie, final CookieOrigin origin) + throws MalformedCookieException { + Args.notNull(cookie, "Cookie"); + Args.notNull(origin, "Cookie origin"); + for (final CookieAttributeHandler handler: getAttribHandlers()) { + handler.validate(cookie, origin); + } + } + + public boolean match(final Cookie cookie, final CookieOrigin origin) { + Args.notNull(cookie, "Cookie"); + Args.notNull(origin, "Cookie origin"); + for (final CookieAttributeHandler handler: getAttribHandlers()) { + if (!handler.match(cookie, origin)) { + return false; + } + } + return true; + } + +} diff --git a/mobile/android/thirdparty/ch/boye/httpclientandroidlib/impl/cookie/DateParseException.java b/mobile/android/thirdparty/ch/boye/httpclientandroidlib/impl/cookie/DateParseException.java new file mode 100644 index 000000000..08b387272 --- /dev/null +++ b/mobile/android/thirdparty/ch/boye/httpclientandroidlib/impl/cookie/DateParseException.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. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * <http://www.apache.org/>. + * + */ + +package ch.boye.httpclientandroidlib.impl.cookie; + +import ch.boye.httpclientandroidlib.annotation.Immutable; + +/** + * An exception to indicate an error parsing a date string. + * + * @see DateUtils + * + * + * @since 4.0 + * + * @deprecated (4.3) no longer used. + */ +@Deprecated +@Immutable +public class DateParseException extends Exception { + + private static final long serialVersionUID = 4417696455000643370L; + + /** + * + */ + public DateParseException() { + super(); + } + + /** + * @param message the exception message + */ + public DateParseException(final String message) { + super(message); + } + +} diff --git a/mobile/android/thirdparty/ch/boye/httpclientandroidlib/impl/cookie/DateUtils.java b/mobile/android/thirdparty/ch/boye/httpclientandroidlib/impl/cookie/DateUtils.java new file mode 100644 index 000000000..897d6fb00 --- /dev/null +++ b/mobile/android/thirdparty/ch/boye/httpclientandroidlib/impl/cookie/DateUtils.java @@ -0,0 +1,156 @@ +/* + * ==================================================================== + * 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. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * <http://www.apache.org/>. + * + */ + +package ch.boye.httpclientandroidlib.impl.cookie; + +import java.util.Date; +import java.util.TimeZone; + +import ch.boye.httpclientandroidlib.annotation.Immutable; + +/** + * 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. + * + * + * @since 4.0 + * + * @deprecated (4.3) Use {@link ch.boye.httpclientandroidlib.client.utils.DateUtils}. + */ +@Deprecated +@Immutable +public final class DateUtils { + + /** + * Date format pattern used to parse HTTP date headers in RFC 1123 format. + */ + public static final String PATTERN_RFC1123 = ch.boye.httpclientandroidlib.client.utils.DateUtils.PATTERN_RFC1123; + + /** + * Date format pattern used to parse HTTP date headers in RFC 1036 format. + */ + public static final String PATTERN_RFC1036 = ch.boye.httpclientandroidlib.client.utils.DateUtils.PATTERN_RFC1036; + + /** + * Date format pattern used to parse HTTP date headers in ANSI C + * <code>asctime()</code> format. + */ + public static final String PATTERN_ASCTIME = ch.boye.httpclientandroidlib.client.utils.DateUtils.PATTERN_ASCTIME; + + public static final TimeZone GMT = TimeZone.getTimeZone("GMT"); + + /** + * 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 + * + * @throws DateParseException if the value could not be parsed using any of the + * supported date formats + */ + public static Date parseDate(final String dateValue) throws DateParseException { + 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 + * + * @throws DateParseException if none of the dataFormats could parse the dateValue + */ + public static Date parseDate(final String dateValue, final String[] dateFormats) + throws DateParseException { + 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 + * + * @throws DateParseException if none of the dataFormats could parse the dateValue + */ + public static Date parseDate( + final String dateValue, + final String[] dateFormats, + final Date startDate + ) throws DateParseException { + final Date d = ch.boye.httpclientandroidlib.client.utils.DateUtils.parseDate(dateValue, dateFormats, startDate); + if (d == null) { + throw new DateParseException("Unable to parse the date " + dateValue); + } + return d; + } + + /** + * 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 ch.boye.httpclientandroidlib.client.utils.DateUtils.formatDate(date); + } + + /** + * Formats the given date according to the specified pattern. The pattern + * must conform to that used by the {@link java.text.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 java.text.SimpleDateFormat + */ + public static String formatDate(final Date date, final String pattern) { + return ch.boye.httpclientandroidlib.client.utils.DateUtils.formatDate(date, pattern); + } + + /** This class should not be instantiated. */ + private DateUtils() { + } + +} diff --git a/mobile/android/thirdparty/ch/boye/httpclientandroidlib/impl/cookie/IgnoreSpec.java b/mobile/android/thirdparty/ch/boye/httpclientandroidlib/impl/cookie/IgnoreSpec.java new file mode 100644 index 000000000..3aa350a40 --- /dev/null +++ b/mobile/android/thirdparty/ch/boye/httpclientandroidlib/impl/cookie/IgnoreSpec.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. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * <http://www.apache.org/>. + * + */ + +package ch.boye.httpclientandroidlib.impl.cookie; + +import java.util.Collections; +import java.util.List; + +import ch.boye.httpclientandroidlib.Header; +import ch.boye.httpclientandroidlib.annotation.NotThreadSafe; +import ch.boye.httpclientandroidlib.cookie.Cookie; +import ch.boye.httpclientandroidlib.cookie.CookieOrigin; +import ch.boye.httpclientandroidlib.cookie.MalformedCookieException; + +/** + * CookieSpec that ignores all cookies + * + * @since 4.1 + */ +@NotThreadSafe // superclass is @NotThreadSafe +public class IgnoreSpec extends CookieSpecBase { + + public int getVersion() { + return 0; + } + + public List<Cookie> parse(final Header header, final CookieOrigin origin) + throws MalformedCookieException { + return Collections.emptyList(); + } + + public List<Header> formatCookies(final List<Cookie> cookies) { + return Collections.emptyList(); + } + + public Header getVersionHeader() { + return null; + } +} diff --git a/mobile/android/thirdparty/ch/boye/httpclientandroidlib/impl/cookie/IgnoreSpecFactory.java b/mobile/android/thirdparty/ch/boye/httpclientandroidlib/impl/cookie/IgnoreSpecFactory.java new file mode 100644 index 000000000..426e25cad --- /dev/null +++ b/mobile/android/thirdparty/ch/boye/httpclientandroidlib/impl/cookie/IgnoreSpecFactory.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. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * <http://www.apache.org/>. + * + */ + +package ch.boye.httpclientandroidlib.impl.cookie; + +import ch.boye.httpclientandroidlib.annotation.Immutable; +import ch.boye.httpclientandroidlib.cookie.CookieSpec; +import ch.boye.httpclientandroidlib.cookie.CookieSpecFactory; +import ch.boye.httpclientandroidlib.cookie.CookieSpecProvider; +import ch.boye.httpclientandroidlib.params.HttpParams; +import ch.boye.httpclientandroidlib.protocol.HttpContext; + +/** + * {@link CookieSpecProvider} implementation that ignores all cookies. + * + * @since 4.1 + */ +@Immutable +@SuppressWarnings("deprecation") +public class IgnoreSpecFactory implements CookieSpecFactory, CookieSpecProvider { + + public IgnoreSpecFactory() { + super(); + } + + public CookieSpec newInstance(final HttpParams params) { + return new IgnoreSpec(); + } + + public CookieSpec create(final HttpContext context) { + return new IgnoreSpec(); + } + +} diff --git a/mobile/android/thirdparty/ch/boye/httpclientandroidlib/impl/cookie/NetscapeDomainHandler.java b/mobile/android/thirdparty/ch/boye/httpclientandroidlib/impl/cookie/NetscapeDomainHandler.java new file mode 100644 index 000000000..adbd40e91 --- /dev/null +++ b/mobile/android/thirdparty/ch/boye/httpclientandroidlib/impl/cookie/NetscapeDomainHandler.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. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * <http://www.apache.org/>. + * + */ +package ch.boye.httpclientandroidlib.impl.cookie; + +import java.util.Locale; +import java.util.StringTokenizer; + +import ch.boye.httpclientandroidlib.annotation.Immutable; +import ch.boye.httpclientandroidlib.cookie.Cookie; +import ch.boye.httpclientandroidlib.cookie.CookieOrigin; +import ch.boye.httpclientandroidlib.cookie.CookieRestrictionViolationException; +import ch.boye.httpclientandroidlib.cookie.MalformedCookieException; +import ch.boye.httpclientandroidlib.util.Args; + +/** + * + * @since 4.0 + */ +@Immutable +public class NetscapeDomainHandler extends BasicDomainHandler { + + public NetscapeDomainHandler() { + super(); + } + + @Override + public void validate(final Cookie cookie, final CookieOrigin origin) + throws MalformedCookieException { + super.validate(cookie, origin); + // Perform Netscape Cookie draft specific validation + final String host = origin.getHost(); + final String domain = cookie.getDomain(); + if (host.contains(".")) { + final int domainParts = new StringTokenizer(domain, ".").countTokens(); + + if (isSpecialDomain(domain)) { + if (domainParts < 2) { + throw new CookieRestrictionViolationException("Domain attribute \"" + + domain + + "\" violates the Netscape cookie specification for " + + "special domains"); + } + } else { + if (domainParts < 3) { + throw new CookieRestrictionViolationException("Domain attribute \"" + + domain + + "\" violates the Netscape cookie specification"); + } + } + } + } + + /** + * Checks if the given domain is in one of the seven special + * top level domains defined by the Netscape cookie specification. + * @param domain The domain. + * @return True if the specified domain is "special" + */ + private static boolean isSpecialDomain(final String domain) { + final String ucDomain = domain.toUpperCase(Locale.ENGLISH); + return ucDomain.endsWith(".COM") + || ucDomain.endsWith(".EDU") + || ucDomain.endsWith(".NET") + || ucDomain.endsWith(".GOV") + || ucDomain.endsWith(".MIL") + || ucDomain.endsWith(".ORG") + || ucDomain.endsWith(".INT"); + } + + @Override + public boolean match(final Cookie cookie, final CookieOrigin origin) { + Args.notNull(cookie, "Cookie"); + Args.notNull(origin, "Cookie origin"); + final String host = origin.getHost(); + final String domain = cookie.getDomain(); + if (domain == null) { + return false; + } + return host.endsWith(domain); + } + +} diff --git a/mobile/android/thirdparty/ch/boye/httpclientandroidlib/impl/cookie/NetscapeDraftHeaderParser.java b/mobile/android/thirdparty/ch/boye/httpclientandroidlib/impl/cookie/NetscapeDraftHeaderParser.java new file mode 100644 index 000000000..89a59688f --- /dev/null +++ b/mobile/android/thirdparty/ch/boye/httpclientandroidlib/impl/cookie/NetscapeDraftHeaderParser.java @@ -0,0 +1,138 @@ +/* + * ==================================================================== + * 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. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * <http://www.apache.org/>. + * + */ + +package ch.boye.httpclientandroidlib.impl.cookie; + +import java.util.ArrayList; +import java.util.List; + +import ch.boye.httpclientandroidlib.HeaderElement; +import ch.boye.httpclientandroidlib.NameValuePair; +import ch.boye.httpclientandroidlib.ParseException; +import ch.boye.httpclientandroidlib.annotation.Immutable; +import ch.boye.httpclientandroidlib.message.BasicHeaderElement; +import ch.boye.httpclientandroidlib.message.BasicNameValuePair; +import ch.boye.httpclientandroidlib.message.ParserCursor; +import ch.boye.httpclientandroidlib.protocol.HTTP; +import ch.boye.httpclientandroidlib.util.Args; +import ch.boye.httpclientandroidlib.util.CharArrayBuffer; + +/** + * + * @since 4.0 + */ +@Immutable +public class NetscapeDraftHeaderParser { + + public final static NetscapeDraftHeaderParser DEFAULT = new NetscapeDraftHeaderParser(); + + public NetscapeDraftHeaderParser() { + super(); + } + + public HeaderElement parseHeader( + final CharArrayBuffer buffer, + final ParserCursor cursor) throws ParseException { + Args.notNull(buffer, "Char array buffer"); + Args.notNull(cursor, "Parser cursor"); + final NameValuePair nvp = parseNameValuePair(buffer, cursor); + final List<NameValuePair> params = new ArrayList<NameValuePair>(); + while (!cursor.atEnd()) { + final NameValuePair param = parseNameValuePair(buffer, cursor); + params.add(param); + } + return new BasicHeaderElement( + nvp.getName(), + nvp.getValue(), params.toArray(new NameValuePair[params.size()])); + } + + private NameValuePair parseNameValuePair( + final CharArrayBuffer buffer, final ParserCursor cursor) { + boolean terminated = false; + + int pos = cursor.getPos(); + final int indexFrom = cursor.getPos(); + final int indexTo = cursor.getUpperBound(); + + // Find name + String name = null; + while (pos < indexTo) { + final char ch = buffer.charAt(pos); + if (ch == '=') { + break; + } + if (ch == ';') { + terminated = true; + break; + } + pos++; + } + + if (pos == indexTo) { + terminated = true; + name = buffer.substringTrimmed(indexFrom, indexTo); + } else { + name = buffer.substringTrimmed(indexFrom, pos); + pos++; + } + + if (terminated) { + cursor.updatePos(pos); + return new BasicNameValuePair(name, null); + } + + // Find value + String value = null; + int i1 = pos; + + while (pos < indexTo) { + final char ch = buffer.charAt(pos); + if (ch == ';') { + terminated = true; + break; + } + pos++; + } + + int i2 = pos; + // Trim leading white spaces + while (i1 < i2 && (HTTP.isWhitespace(buffer.charAt(i1)))) { + i1++; + } + // Trim trailing white spaces + while ((i2 > i1) && (HTTP.isWhitespace(buffer.charAt(i2 - 1)))) { + i2--; + } + value = buffer.substring(i1, i2); + if (terminated) { + pos++; + } + cursor.updatePos(pos); + return new BasicNameValuePair(name, value); + } + +} diff --git a/mobile/android/thirdparty/ch/boye/httpclientandroidlib/impl/cookie/NetscapeDraftSpec.java b/mobile/android/thirdparty/ch/boye/httpclientandroidlib/impl/cookie/NetscapeDraftSpec.java new file mode 100644 index 000000000..139e5985c --- /dev/null +++ b/mobile/android/thirdparty/ch/boye/httpclientandroidlib/impl/cookie/NetscapeDraftSpec.java @@ -0,0 +1,171 @@ +/* + * ==================================================================== + * 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. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * <http://www.apache.org/>. + * + */ + +package ch.boye.httpclientandroidlib.impl.cookie; + +import java.util.ArrayList; +import java.util.List; + +import ch.boye.httpclientandroidlib.FormattedHeader; +import ch.boye.httpclientandroidlib.Header; +import ch.boye.httpclientandroidlib.HeaderElement; +import ch.boye.httpclientandroidlib.annotation.NotThreadSafe; +import ch.boye.httpclientandroidlib.cookie.ClientCookie; +import ch.boye.httpclientandroidlib.cookie.Cookie; +import ch.boye.httpclientandroidlib.cookie.CookieOrigin; +import ch.boye.httpclientandroidlib.cookie.MalformedCookieException; +import ch.boye.httpclientandroidlib.cookie.SM; +import ch.boye.httpclientandroidlib.message.BufferedHeader; +import ch.boye.httpclientandroidlib.message.ParserCursor; +import ch.boye.httpclientandroidlib.util.Args; +import ch.boye.httpclientandroidlib.util.CharArrayBuffer; + +/** + * This {@link ch.boye.httpclientandroidlib.cookie.CookieSpec} implementation conforms to + * the original draft specification published by Netscape Communications. + * It should be avoided unless absolutely necessary for compatibility with + * legacy applications. + * + * @since 4.0 + */ +@NotThreadSafe // superclass is @NotThreadSafe +public class NetscapeDraftSpec extends CookieSpecBase { + + protected static final String EXPIRES_PATTERN = "EEE, dd-MMM-yy HH:mm:ss z"; + + private final String[] datepatterns; + + /** Default constructor */ + public NetscapeDraftSpec(final String[] datepatterns) { + super(); + if (datepatterns != null) { + this.datepatterns = datepatterns.clone(); + } else { + this.datepatterns = new String[] { EXPIRES_PATTERN }; + } + registerAttribHandler(ClientCookie.PATH_ATTR, new BasicPathHandler()); + registerAttribHandler(ClientCookie.DOMAIN_ATTR, new NetscapeDomainHandler()); + registerAttribHandler(ClientCookie.MAX_AGE_ATTR, new BasicMaxAgeHandler()); + registerAttribHandler(ClientCookie.SECURE_ATTR, new BasicSecureHandler()); + registerAttribHandler(ClientCookie.COMMENT_ATTR, new BasicCommentHandler()); + registerAttribHandler(ClientCookie.EXPIRES_ATTR, new BasicExpiresHandler( + this.datepatterns)); + } + + /** Default constructor */ + public NetscapeDraftSpec() { + this(null); + } + + /** + * Parses the Set-Cookie value into an array of <tt>Cookie</tt>s. + * + * <p>Syntax of the Set-Cookie HTTP Response Header:</p> + * + * <p>This is the format a CGI script would use to add to + * the HTTP headers a new piece of data which is to be stored by + * the client for later retrieval.</p> + * + * <PRE> + * Set-Cookie: NAME=VALUE; expires=DATE; path=PATH; domain=DOMAIN_NAME; secure + * </PRE> + * + * <p>Please note that the Netscape draft specification does not fully conform to the HTTP + * header format. Comma character if present in <code>Set-Cookie</code> will not be treated + * as a header element separator</p> + * + * @see <a href="http://web.archive.org/web/20020803110822/http://wp.netscape.com/newsref/std/cookie_spec.html"> + * The Cookie Spec.</a> + * + * @param header the <tt>Set-Cookie</tt> received from the server + * @return an array of <tt>Cookie</tt>s parsed from the Set-Cookie value + * @throws MalformedCookieException if an exception occurs during parsing + */ + public List<Cookie> parse(final Header header, final CookieOrigin origin) + throws MalformedCookieException { + Args.notNull(header, "Header"); + Args.notNull(origin, "Cookie origin"); + if (!header.getName().equalsIgnoreCase(SM.SET_COOKIE)) { + throw new MalformedCookieException("Unrecognized cookie header '" + + header.toString() + "'"); + } + final NetscapeDraftHeaderParser parser = NetscapeDraftHeaderParser.DEFAULT; + final CharArrayBuffer buffer; + final ParserCursor cursor; + if (header instanceof FormattedHeader) { + buffer = ((FormattedHeader) header).getBuffer(); + cursor = new ParserCursor( + ((FormattedHeader) header).getValuePos(), + buffer.length()); + } else { + final String s = header.getValue(); + if (s == null) { + throw new MalformedCookieException("Header value is null"); + } + buffer = new CharArrayBuffer(s.length()); + buffer.append(s); + cursor = new ParserCursor(0, buffer.length()); + } + return parse(new HeaderElement[] { parser.parseHeader(buffer, cursor) }, origin); + } + + public List<Header> formatCookies(final List<Cookie> cookies) { + Args.notEmpty(cookies, "List of cookies"); + final CharArrayBuffer buffer = new CharArrayBuffer(20 * cookies.size()); + buffer.append(SM.COOKIE); + buffer.append(": "); + for (int i = 0; i < cookies.size(); i++) { + final Cookie cookie = cookies.get(i); + if (i > 0) { + buffer.append("; "); + } + buffer.append(cookie.getName()); + final String s = cookie.getValue(); + if (s != null) { + buffer.append("="); + buffer.append(s); + } + } + final List<Header> headers = new ArrayList<Header>(1); + headers.add(new BufferedHeader(buffer)); + return headers; + } + + public int getVersion() { + return 0; + } + + public Header getVersionHeader() { + return null; + } + + @Override + public String toString() { + return "netscape"; + } + +} diff --git a/mobile/android/thirdparty/ch/boye/httpclientandroidlib/impl/cookie/NetscapeDraftSpecFactory.java b/mobile/android/thirdparty/ch/boye/httpclientandroidlib/impl/cookie/NetscapeDraftSpecFactory.java new file mode 100644 index 000000000..d1187a150 --- /dev/null +++ b/mobile/android/thirdparty/ch/boye/httpclientandroidlib/impl/cookie/NetscapeDraftSpecFactory.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. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * <http://www.apache.org/>. + * + */ + +package ch.boye.httpclientandroidlib.impl.cookie; + +import java.util.Collection; + +import ch.boye.httpclientandroidlib.annotation.Immutable; +import ch.boye.httpclientandroidlib.cookie.CookieSpec; +import ch.boye.httpclientandroidlib.cookie.CookieSpecFactory; +import ch.boye.httpclientandroidlib.cookie.CookieSpecProvider; +import ch.boye.httpclientandroidlib.cookie.params.CookieSpecPNames; +import ch.boye.httpclientandroidlib.params.HttpParams; +import ch.boye.httpclientandroidlib.protocol.HttpContext; + +/** + * {@link CookieSpecProvider} implementation that creates and initializes + * {@link NetscapeDraftSpec} instances. + * + * @since 4.0 + */ +@Immutable +@SuppressWarnings("deprecation") +public class NetscapeDraftSpecFactory implements CookieSpecFactory, CookieSpecProvider { + + private final String[] datepatterns; + + public NetscapeDraftSpecFactory(final String[] datepatterns) { + super(); + this.datepatterns = datepatterns; + } + + public NetscapeDraftSpecFactory() { + this(null); + } + + public CookieSpec newInstance(final HttpParams params) { + if (params != null) { + + String[] patterns = null; + final Collection<?> param = (Collection<?>) params.getParameter( + CookieSpecPNames.DATE_PATTERNS); + if (param != null) { + patterns = new String[param.size()]; + patterns = param.toArray(patterns); + } + return new NetscapeDraftSpec(patterns); + } else { + return new NetscapeDraftSpec(); + } + } + + public CookieSpec create(final HttpContext context) { + return new NetscapeDraftSpec(this.datepatterns); + } + +} diff --git a/mobile/android/thirdparty/ch/boye/httpclientandroidlib/impl/cookie/PublicSuffixFilter.java b/mobile/android/thirdparty/ch/boye/httpclientandroidlib/impl/cookie/PublicSuffixFilter.java new file mode 100644 index 000000000..4777918ba --- /dev/null +++ b/mobile/android/thirdparty/ch/boye/httpclientandroidlib/impl/cookie/PublicSuffixFilter.java @@ -0,0 +1,132 @@ +/* + * ==================================================================== + * 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. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * <http://www.apache.org/>. + * + */ +package ch.boye.httpclientandroidlib.impl.cookie; + +import java.util.Collection; +import java.util.HashSet; +import java.util.Set; + +import ch.boye.httpclientandroidlib.client.utils.Punycode; +import ch.boye.httpclientandroidlib.cookie.Cookie; +import ch.boye.httpclientandroidlib.cookie.CookieAttributeHandler; +import ch.boye.httpclientandroidlib.cookie.CookieOrigin; +import ch.boye.httpclientandroidlib.cookie.MalformedCookieException; +import ch.boye.httpclientandroidlib.cookie.SetCookie; + +/** + * Wraps a CookieAttributeHandler and leverages its match method + * to never match a suffix from a black list. May be used to provide + * additional security for cross-site attack types by preventing + * cookies from apparent domains that are not publicly available. + * An uptodate list of suffixes can be obtained from + * <a href="http://publicsuffix.org/">publicsuffix.org</a> + * + * @since 4.0 + */ +public class PublicSuffixFilter implements CookieAttributeHandler { + private final CookieAttributeHandler wrapped; + private Set<String> exceptions; + private Set<String> suffixes; + + public PublicSuffixFilter(final CookieAttributeHandler wrapped) { + this.wrapped = wrapped; + } + + /** + * Sets the suffix blacklist patterns. + * A pattern can be "com", "*.jp" + * TODO add support for patterns like "lib.*.us" + * @param suffixes + */ + public void setPublicSuffixes(final Collection<String> suffixes) { + this.suffixes = new HashSet<String>(suffixes); + } + + /** + * Sets the exceptions from the blacklist. Exceptions can not be patterns. + * TODO add support for patterns + * @param exceptions + */ + public void setExceptions(final Collection<String> exceptions) { + this.exceptions = new HashSet<String>(exceptions); + } + + /** + * Never matches if the cookie's domain is from the blacklist. + */ + public boolean match(final Cookie cookie, final CookieOrigin origin) { + if (isForPublicSuffix(cookie)) { + return false; + } + return wrapped.match(cookie, origin); + } + + public void parse(final SetCookie cookie, final String value) throws MalformedCookieException { + wrapped.parse(cookie, value); + } + + public void validate(final Cookie cookie, final CookieOrigin origin) throws MalformedCookieException { + wrapped.validate(cookie, origin); + } + + private boolean isForPublicSuffix(final Cookie cookie) { + String domain = cookie.getDomain(); + if (domain.startsWith(".")) { + domain = domain.substring(1); + } + domain = Punycode.toUnicode(domain); + + // An exception rule takes priority over any other matching rule. + if (this.exceptions != null) { + if (this.exceptions.contains(domain)) { + return false; + } + } + + + if (this.suffixes == null) { + return false; + } + + do { + if (this.suffixes.contains(domain)) { + return true; + } + // patterns + if (domain.startsWith("*.")) { + domain = domain.substring(2); + } + final int nextdot = domain.indexOf('.'); + if (nextdot == -1) { + break; + } + domain = "*" + domain.substring(nextdot); + } while (domain.length() > 0); + + return false; + } +} diff --git a/mobile/android/thirdparty/ch/boye/httpclientandroidlib/impl/cookie/PublicSuffixListParser.java b/mobile/android/thirdparty/ch/boye/httpclientandroidlib/impl/cookie/PublicSuffixListParser.java new file mode 100644 index 000000000..4f0374f99 --- /dev/null +++ b/mobile/android/thirdparty/ch/boye/httpclientandroidlib/impl/cookie/PublicSuffixListParser.java @@ -0,0 +1,127 @@ +/* + * ==================================================================== + * 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. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * <http://www.apache.org/>. + * + */ +package ch.boye.httpclientandroidlib.impl.cookie; + +import java.io.BufferedReader; +import java.io.IOException; +import java.io.Reader; +import java.util.ArrayList; +import java.util.Collection; + +import ch.boye.httpclientandroidlib.annotation.Immutable; + +/** + * Parses the list from <a href="http://publicsuffix.org/">publicsuffix.org</a> + * and configures a PublicSuffixFilter. + * + * @since 4.0 + */ +@Immutable +public class PublicSuffixListParser { + private static final int MAX_LINE_LEN = 256; + private final PublicSuffixFilter filter; + + PublicSuffixListParser(final PublicSuffixFilter filter) { + this.filter = filter; + } + + /** + * Parses the public suffix list format. + * When creating the reader from the file, make sure to + * use the correct encoding (the original list is in UTF-8). + * + * @param list the suffix list. The caller is responsible for closing the reader. + * @throws IOException on error while reading from list + */ + public void parse(final Reader list) throws IOException { + final Collection<String> rules = new ArrayList<String>(); + final Collection<String> exceptions = new ArrayList<String>(); + final BufferedReader r = new BufferedReader(list); + final StringBuilder sb = new StringBuilder(256); + boolean more = true; + while (more) { + more = readLine(r, sb); + String line = sb.toString(); + if (line.length() == 0) { + continue; + } + if (line.startsWith("//")) + { + continue; //entire lines can also be commented using // + } + if (line.startsWith(".")) + { + line = line.substring(1); // A leading dot is optional + } + // An exclamation mark (!) at the start of a rule marks an exception to a previous wildcard rule + final boolean isException = line.startsWith("!"); + if (isException) { + line = line.substring(1); + } + + if (isException) { + exceptions.add(line); + } else { + rules.add(line); + } + } + + filter.setPublicSuffixes(rules); + filter.setExceptions(exceptions); + } + + /** + * + * @param r + * @param sb + * @return false when the end of the stream is reached + * @throws IOException + */ + private boolean readLine(final Reader r, final StringBuilder sb) throws IOException { + sb.setLength(0); + int b; + boolean hitWhitespace = false; + while ((b = r.read()) != -1) { + final char c = (char) b; + if (c == '\n') { + break; + } + // Each line is only read up to the first whitespace + if (Character.isWhitespace(c)) { + hitWhitespace = true; + } + if (!hitWhitespace) { + sb.append(c); + } + if (sb.length() > MAX_LINE_LEN) + { + throw new IOException("Line too long"); // prevent excess memory usage + } + } + return (b != -1); + } +} diff --git a/mobile/android/thirdparty/ch/boye/httpclientandroidlib/impl/cookie/RFC2109DomainHandler.java b/mobile/android/thirdparty/ch/boye/httpclientandroidlib/impl/cookie/RFC2109DomainHandler.java new file mode 100644 index 000000000..d669dcb43 --- /dev/null +++ b/mobile/android/thirdparty/ch/boye/httpclientandroidlib/impl/cookie/RFC2109DomainHandler.java @@ -0,0 +1,120 @@ +/* + * ==================================================================== + * 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. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * <http://www.apache.org/>. + * + */ +package ch.boye.httpclientandroidlib.impl.cookie; + +import java.util.Locale; + +import ch.boye.httpclientandroidlib.annotation.Immutable; +import ch.boye.httpclientandroidlib.cookie.Cookie; +import ch.boye.httpclientandroidlib.cookie.CookieAttributeHandler; +import ch.boye.httpclientandroidlib.cookie.CookieOrigin; +import ch.boye.httpclientandroidlib.cookie.CookieRestrictionViolationException; +import ch.boye.httpclientandroidlib.cookie.MalformedCookieException; +import ch.boye.httpclientandroidlib.cookie.SetCookie; +import ch.boye.httpclientandroidlib.util.Args; + +/** + * + * @since 4.0 + */ +@Immutable +public class RFC2109DomainHandler implements CookieAttributeHandler { + + public RFC2109DomainHandler() { + super(); + } + + public void parse(final SetCookie cookie, final String value) + throws MalformedCookieException { + Args.notNull(cookie, "Cookie"); + if (value == null) { + throw new MalformedCookieException("Missing value for domain attribute"); + } + if (value.trim().length() == 0) { + throw new MalformedCookieException("Blank value for domain attribute"); + } + cookie.setDomain(value); + } + + public void validate(final Cookie cookie, final CookieOrigin origin) + throws MalformedCookieException { + Args.notNull(cookie, "Cookie"); + Args.notNull(origin, "Cookie origin"); + String host = origin.getHost(); + final String domain = cookie.getDomain(); + if (domain == null) { + throw new CookieRestrictionViolationException("Cookie domain may not be null"); + } + if (!domain.equals(host)) { + int dotIndex = domain.indexOf('.'); + if (dotIndex == -1) { + throw new CookieRestrictionViolationException("Domain attribute \"" + + domain + + "\" does not match the host \"" + + host + "\""); + } + // domain must start with dot + if (!domain.startsWith(".")) { + throw new CookieRestrictionViolationException("Domain attribute \"" + + domain + + "\" violates RFC 2109: domain must start with a dot"); + } + // domain must have at least one embedded dot + dotIndex = domain.indexOf('.', 1); + if (dotIndex < 0 || dotIndex == domain.length() - 1) { + throw new CookieRestrictionViolationException("Domain attribute \"" + + domain + + "\" violates RFC 2109: domain must contain an embedded dot"); + } + host = host.toLowerCase(Locale.ENGLISH); + if (!host.endsWith(domain)) { + throw new CookieRestrictionViolationException( + "Illegal domain attribute \"" + domain + + "\". Domain of origin: \"" + host + "\""); + } + // host minus domain may not contain any dots + final String hostWithoutDomain = host.substring(0, host.length() - domain.length()); + if (hostWithoutDomain.indexOf('.') != -1) { + throw new CookieRestrictionViolationException("Domain attribute \"" + + domain + + "\" violates RFC 2109: host minus domain may not contain any dots"); + } + } + } + + public boolean match(final Cookie cookie, final CookieOrigin origin) { + Args.notNull(cookie, "Cookie"); + Args.notNull(origin, "Cookie origin"); + final String host = origin.getHost(); + final String domain = cookie.getDomain(); + if (domain == null) { + return false; + } + return host.equals(domain) || (domain.startsWith(".") && host.endsWith(domain)); + } + +} diff --git a/mobile/android/thirdparty/ch/boye/httpclientandroidlib/impl/cookie/RFC2109Spec.java b/mobile/android/thirdparty/ch/boye/httpclientandroidlib/impl/cookie/RFC2109Spec.java new file mode 100644 index 000000000..1292788a0 --- /dev/null +++ b/mobile/android/thirdparty/ch/boye/httpclientandroidlib/impl/cookie/RFC2109Spec.java @@ -0,0 +1,240 @@ +/* + * ==================================================================== + * 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. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * <http://www.apache.org/>. + * + */ + +package ch.boye.httpclientandroidlib.impl.cookie; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +import ch.boye.httpclientandroidlib.Header; +import ch.boye.httpclientandroidlib.HeaderElement; +import ch.boye.httpclientandroidlib.annotation.NotThreadSafe; +import ch.boye.httpclientandroidlib.client.utils.DateUtils; +import ch.boye.httpclientandroidlib.cookie.ClientCookie; +import ch.boye.httpclientandroidlib.cookie.Cookie; +import ch.boye.httpclientandroidlib.cookie.CookieOrigin; +import ch.boye.httpclientandroidlib.cookie.CookiePathComparator; +import ch.boye.httpclientandroidlib.cookie.CookieRestrictionViolationException; +import ch.boye.httpclientandroidlib.cookie.MalformedCookieException; +import ch.boye.httpclientandroidlib.cookie.SM; +import ch.boye.httpclientandroidlib.message.BufferedHeader; +import ch.boye.httpclientandroidlib.util.Args; +import ch.boye.httpclientandroidlib.util.CharArrayBuffer; + +/** + * RFC 2109 compliant {@link ch.boye.httpclientandroidlib.cookie.CookieSpec} implementation. + * This is an older version of the official HTTP state management specification + * superseded by RFC 2965. + * + * @see RFC2965Spec + * + * @since 4.0 + */ +@NotThreadSafe // superclass is @NotThreadSafe +public class RFC2109Spec extends CookieSpecBase { + + private final static CookiePathComparator PATH_COMPARATOR = new CookiePathComparator(); + + private final static String[] DATE_PATTERNS = { + DateUtils.PATTERN_RFC1123, + DateUtils.PATTERN_RFC1036, + DateUtils.PATTERN_ASCTIME + }; + + private final String[] datepatterns; + private final boolean oneHeader; + + /** Default constructor */ + public RFC2109Spec(final String[] datepatterns, final boolean oneHeader) { + super(); + if (datepatterns != null) { + this.datepatterns = datepatterns.clone(); + } else { + this.datepatterns = DATE_PATTERNS; + } + this.oneHeader = oneHeader; + registerAttribHandler(ClientCookie.VERSION_ATTR, new RFC2109VersionHandler()); + registerAttribHandler(ClientCookie.PATH_ATTR, new BasicPathHandler()); + registerAttribHandler(ClientCookie.DOMAIN_ATTR, new RFC2109DomainHandler()); + registerAttribHandler(ClientCookie.MAX_AGE_ATTR, new BasicMaxAgeHandler()); + registerAttribHandler(ClientCookie.SECURE_ATTR, new BasicSecureHandler()); + registerAttribHandler(ClientCookie.COMMENT_ATTR, new BasicCommentHandler()); + registerAttribHandler(ClientCookie.EXPIRES_ATTR, new BasicExpiresHandler( + this.datepatterns)); + } + + /** Default constructor */ + public RFC2109Spec() { + this(null, false); + } + + public List<Cookie> parse(final Header header, final CookieOrigin origin) + throws MalformedCookieException { + Args.notNull(header, "Header"); + Args.notNull(origin, "Cookie origin"); + if (!header.getName().equalsIgnoreCase(SM.SET_COOKIE)) { + throw new MalformedCookieException("Unrecognized cookie header '" + + header.toString() + "'"); + } + final HeaderElement[] elems = header.getElements(); + return parse(elems, origin); + } + + @Override + public void validate(final Cookie cookie, final CookieOrigin origin) + throws MalformedCookieException { + Args.notNull(cookie, "Cookie"); + final String name = cookie.getName(); + if (name.indexOf(' ') != -1) { + throw new CookieRestrictionViolationException("Cookie name may not contain blanks"); + } + if (name.startsWith("$")) { + throw new CookieRestrictionViolationException("Cookie name may not start with $"); + } + super.validate(cookie, origin); + } + + public List<Header> formatCookies(final List<Cookie> cookies) { + Args.notEmpty(cookies, "List of cookies"); + List<Cookie> cookieList; + if (cookies.size() > 1) { + // Create a mutable copy and sort the copy. + cookieList = new ArrayList<Cookie>(cookies); + Collections.sort(cookieList, PATH_COMPARATOR); + } else { + cookieList = cookies; + } + if (this.oneHeader) { + return doFormatOneHeader(cookieList); + } else { + return doFormatManyHeaders(cookieList); + } + } + + private List<Header> doFormatOneHeader(final List<Cookie> cookies) { + int version = Integer.MAX_VALUE; + // Pick the lowest common denominator + for (final Cookie cookie : cookies) { + if (cookie.getVersion() < version) { + version = cookie.getVersion(); + } + } + final CharArrayBuffer buffer = new CharArrayBuffer(40 * cookies.size()); + buffer.append(SM.COOKIE); + buffer.append(": "); + buffer.append("$Version="); + buffer.append(Integer.toString(version)); + for (final Cookie cooky : cookies) { + buffer.append("; "); + final Cookie cookie = cooky; + formatCookieAsVer(buffer, cookie, version); + } + final List<Header> headers = new ArrayList<Header>(1); + headers.add(new BufferedHeader(buffer)); + return headers; + } + + private List<Header> doFormatManyHeaders(final List<Cookie> cookies) { + final List<Header> headers = new ArrayList<Header>(cookies.size()); + for (final Cookie cookie : cookies) { + final int version = cookie.getVersion(); + final CharArrayBuffer buffer = new CharArrayBuffer(40); + buffer.append("Cookie: "); + buffer.append("$Version="); + buffer.append(Integer.toString(version)); + buffer.append("; "); + formatCookieAsVer(buffer, cookie, version); + headers.add(new BufferedHeader(buffer)); + } + return headers; + } + + /** + * Return a name/value string suitable for sending in a <tt>"Cookie"</tt> + * header as defined in RFC 2109 for backward compatibility with cookie + * version 0 + * @param buffer The char array buffer to use for output + * @param name The cookie name + * @param value The cookie value + * @param version The cookie version + */ + protected void formatParamAsVer(final CharArrayBuffer buffer, + final String name, final String value, final int version) { + buffer.append(name); + buffer.append("="); + if (value != null) { + if (version > 0) { + buffer.append('\"'); + buffer.append(value); + buffer.append('\"'); + } else { + buffer.append(value); + } + } + } + + /** + * Return a string suitable for sending in a <tt>"Cookie"</tt> header + * as defined in RFC 2109 for backward compatibility with cookie version 0 + * @param buffer The char array buffer to use for output + * @param cookie The {@link Cookie} to be formatted as string + * @param version The version to use. + */ + protected void formatCookieAsVer(final CharArrayBuffer buffer, + final Cookie cookie, final int version) { + formatParamAsVer(buffer, cookie.getName(), cookie.getValue(), version); + if (cookie.getPath() != null) { + if (cookie instanceof ClientCookie + && ((ClientCookie) cookie).containsAttribute(ClientCookie.PATH_ATTR)) { + buffer.append("; "); + formatParamAsVer(buffer, "$Path", cookie.getPath(), version); + } + } + if (cookie.getDomain() != null) { + if (cookie instanceof ClientCookie + && ((ClientCookie) cookie).containsAttribute(ClientCookie.DOMAIN_ATTR)) { + buffer.append("; "); + formatParamAsVer(buffer, "$Domain", cookie.getDomain(), version); + } + } + } + + public int getVersion() { + return 1; + } + + public Header getVersionHeader() { + return null; + } + + @Override + public String toString() { + return "rfc2109"; + } + +} diff --git a/mobile/android/thirdparty/ch/boye/httpclientandroidlib/impl/cookie/RFC2109SpecFactory.java b/mobile/android/thirdparty/ch/boye/httpclientandroidlib/impl/cookie/RFC2109SpecFactory.java new file mode 100644 index 000000000..24802c351 --- /dev/null +++ b/mobile/android/thirdparty/ch/boye/httpclientandroidlib/impl/cookie/RFC2109SpecFactory.java @@ -0,0 +1,86 @@ +/* + * ==================================================================== + * 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. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * <http://www.apache.org/>. + * + */ + +package ch.boye.httpclientandroidlib.impl.cookie; + +import java.util.Collection; + +import ch.boye.httpclientandroidlib.annotation.Immutable; +import ch.boye.httpclientandroidlib.cookie.CookieSpec; +import ch.boye.httpclientandroidlib.cookie.CookieSpecFactory; +import ch.boye.httpclientandroidlib.cookie.CookieSpecProvider; +import ch.boye.httpclientandroidlib.cookie.params.CookieSpecPNames; +import ch.boye.httpclientandroidlib.params.HttpParams; +import ch.boye.httpclientandroidlib.protocol.HttpContext; + +/** + * {@link CookieSpecProvider} implementation that creates and initializes + * {@link RFC2109Spec} instances. + * + * @since 4.0 + */ +@Immutable +@SuppressWarnings("deprecation") +public class RFC2109SpecFactory implements CookieSpecFactory, CookieSpecProvider { + + private final String[] datepatterns; + private final boolean oneHeader; + + public RFC2109SpecFactory(final String[] datepatterns, final boolean oneHeader) { + super(); + this.datepatterns = datepatterns; + this.oneHeader = oneHeader; + } + + public RFC2109SpecFactory() { + this(null, false); + } + + public CookieSpec newInstance(final HttpParams params) { + if (params != null) { + + String[] patterns = null; + final Collection<?> param = (Collection<?>) params.getParameter( + CookieSpecPNames.DATE_PATTERNS); + if (param != null) { + patterns = new String[param.size()]; + patterns = param.toArray(patterns); + } + final boolean singleHeader = params.getBooleanParameter( + CookieSpecPNames.SINGLE_COOKIE_HEADER, false); + + return new RFC2109Spec(patterns, singleHeader); + } else { + return new RFC2109Spec(); + } + } + + public CookieSpec create(final HttpContext context) { + return new RFC2109Spec(this.datepatterns, this.oneHeader); + } + +} diff --git a/mobile/android/thirdparty/ch/boye/httpclientandroidlib/impl/cookie/RFC2109VersionHandler.java b/mobile/android/thirdparty/ch/boye/httpclientandroidlib/impl/cookie/RFC2109VersionHandler.java new file mode 100644 index 000000000..a43fe9b22 --- /dev/null +++ b/mobile/android/thirdparty/ch/boye/httpclientandroidlib/impl/cookie/RFC2109VersionHandler.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. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * <http://www.apache.org/>. + * + */ +package ch.boye.httpclientandroidlib.impl.cookie; + +import ch.boye.httpclientandroidlib.annotation.Immutable; +import ch.boye.httpclientandroidlib.cookie.Cookie; +import ch.boye.httpclientandroidlib.cookie.CookieOrigin; +import ch.boye.httpclientandroidlib.cookie.CookieRestrictionViolationException; +import ch.boye.httpclientandroidlib.cookie.MalformedCookieException; +import ch.boye.httpclientandroidlib.cookie.SetCookie; +import ch.boye.httpclientandroidlib.util.Args; + +/** + * + * @since 4.0 + */ +@Immutable +public class RFC2109VersionHandler extends AbstractCookieAttributeHandler { + + public RFC2109VersionHandler() { + super(); + } + + public void parse(final SetCookie cookie, final String value) + throws MalformedCookieException { + Args.notNull(cookie, "Cookie"); + if (value == null) { + throw new MalformedCookieException("Missing value for version attribute"); + } + if (value.trim().length() == 0) { + throw new MalformedCookieException("Blank value for version attribute"); + } + try { + cookie.setVersion(Integer.parseInt(value)); + } catch (final NumberFormatException e) { + throw new MalformedCookieException("Invalid version: " + + e.getMessage()); + } + } + + @Override + public void validate(final Cookie cookie, final CookieOrigin origin) + throws MalformedCookieException { + Args.notNull(cookie, "Cookie"); + if (cookie.getVersion() < 0) { + throw new CookieRestrictionViolationException("Cookie version may not be negative"); + } + } + +} diff --git a/mobile/android/thirdparty/ch/boye/httpclientandroidlib/impl/cookie/RFC2965CommentUrlAttributeHandler.java b/mobile/android/thirdparty/ch/boye/httpclientandroidlib/impl/cookie/RFC2965CommentUrlAttributeHandler.java new file mode 100644 index 000000000..10f5f40ec --- /dev/null +++ b/mobile/android/thirdparty/ch/boye/httpclientandroidlib/impl/cookie/RFC2965CommentUrlAttributeHandler.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. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * <http://www.apache.org/>. + * + */ + +package ch.boye.httpclientandroidlib.impl.cookie; + +import ch.boye.httpclientandroidlib.annotation.Immutable; +import ch.boye.httpclientandroidlib.cookie.Cookie; +import ch.boye.httpclientandroidlib.cookie.CookieAttributeHandler; +import ch.boye.httpclientandroidlib.cookie.CookieOrigin; +import ch.boye.httpclientandroidlib.cookie.MalformedCookieException; +import ch.boye.httpclientandroidlib.cookie.SetCookie; +import ch.boye.httpclientandroidlib.cookie.SetCookie2; + +/** + * <tt>"CommentURL"</tt> cookie attribute handler for RFC 2965 cookie spec. + * + * @since 4.0 + */ +@Immutable +public class RFC2965CommentUrlAttributeHandler implements CookieAttributeHandler { + + public RFC2965CommentUrlAttributeHandler() { + super(); + } + + public void parse(final SetCookie cookie, final String commenturl) + throws MalformedCookieException { + if (cookie instanceof SetCookie2) { + final SetCookie2 cookie2 = (SetCookie2) cookie; + cookie2.setCommentURL(commenturl); + } + } + + public void validate(final Cookie cookie, final CookieOrigin origin) + throws MalformedCookieException { + } + + public boolean match(final Cookie cookie, final CookieOrigin origin) { + return true; + } + + } diff --git a/mobile/android/thirdparty/ch/boye/httpclientandroidlib/impl/cookie/RFC2965DiscardAttributeHandler.java b/mobile/android/thirdparty/ch/boye/httpclientandroidlib/impl/cookie/RFC2965DiscardAttributeHandler.java new file mode 100644 index 000000000..c4bfca460 --- /dev/null +++ b/mobile/android/thirdparty/ch/boye/httpclientandroidlib/impl/cookie/RFC2965DiscardAttributeHandler.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. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * <http://www.apache.org/>. + * + */ + +package ch.boye.httpclientandroidlib.impl.cookie; + +import ch.boye.httpclientandroidlib.annotation.Immutable; +import ch.boye.httpclientandroidlib.cookie.Cookie; +import ch.boye.httpclientandroidlib.cookie.CookieAttributeHandler; +import ch.boye.httpclientandroidlib.cookie.CookieOrigin; +import ch.boye.httpclientandroidlib.cookie.MalformedCookieException; +import ch.boye.httpclientandroidlib.cookie.SetCookie; +import ch.boye.httpclientandroidlib.cookie.SetCookie2; + +/** + * <tt>"Discard"</tt> cookie attribute handler for RFC 2965 cookie spec. + * + * @since 4.0 + */ +@Immutable +public class RFC2965DiscardAttributeHandler implements CookieAttributeHandler { + + public RFC2965DiscardAttributeHandler() { + super(); + } + + public void parse(final SetCookie cookie, final String commenturl) + throws MalformedCookieException { + if (cookie instanceof SetCookie2) { + final SetCookie2 cookie2 = (SetCookie2) cookie; + cookie2.setDiscard(true); + } + } + + public void validate(final Cookie cookie, final CookieOrigin origin) + throws MalformedCookieException { + } + + public boolean match(final Cookie cookie, final CookieOrigin origin) { + return true; + } + + } diff --git a/mobile/android/thirdparty/ch/boye/httpclientandroidlib/impl/cookie/RFC2965DomainAttributeHandler.java b/mobile/android/thirdparty/ch/boye/httpclientandroidlib/impl/cookie/RFC2965DomainAttributeHandler.java new file mode 100644 index 000000000..62c947c55 --- /dev/null +++ b/mobile/android/thirdparty/ch/boye/httpclientandroidlib/impl/cookie/RFC2965DomainAttributeHandler.java @@ -0,0 +1,185 @@ +/* + * ==================================================================== + * 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. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * <http://www.apache.org/>. + * + */ + +package ch.boye.httpclientandroidlib.impl.cookie; + +import java.util.Locale; + +import ch.boye.httpclientandroidlib.annotation.Immutable; +import ch.boye.httpclientandroidlib.cookie.ClientCookie; +import ch.boye.httpclientandroidlib.cookie.Cookie; +import ch.boye.httpclientandroidlib.cookie.CookieAttributeHandler; +import ch.boye.httpclientandroidlib.cookie.CookieOrigin; +import ch.boye.httpclientandroidlib.cookie.CookieRestrictionViolationException; +import ch.boye.httpclientandroidlib.cookie.MalformedCookieException; +import ch.boye.httpclientandroidlib.cookie.SetCookie; +import ch.boye.httpclientandroidlib.util.Args; + +/** + * <tt>"Domain"</tt> cookie attribute handler for RFC 2965 cookie spec. + * + * + * @since 3.1 + */ +@Immutable +public class RFC2965DomainAttributeHandler implements CookieAttributeHandler { + + public RFC2965DomainAttributeHandler() { + super(); + } + + /** + * Parse cookie domain attribute. + */ + public void parse( + final SetCookie cookie, final String domain) throws MalformedCookieException { + Args.notNull(cookie, "Cookie"); + if (domain == null) { + throw new MalformedCookieException( + "Missing value for domain attribute"); + } + if (domain.trim().length() == 0) { + throw new MalformedCookieException( + "Blank value for domain attribute"); + } + String s = domain; + s = s.toLowerCase(Locale.ENGLISH); + if (!domain.startsWith(".")) { + // Per RFC 2965 section 3.2.2 + // "... If an explicitly specified value does not start with + // a dot, the user agent supplies a leading dot ..." + // That effectively implies that the domain attribute + // MAY NOT be an IP address of a host name + s = '.' + s; + } + cookie.setDomain(s); + } + + /** + * Performs domain-match as defined by the RFC2965. + * <p> + * Host A's name domain-matches host B's if + * <ol> + * <ul>their host name strings string-compare equal; or</ul> + * <ul>A is a HDN string and has the form NB, where N is a non-empty + * name string, B has the form .B', and B' is a HDN string. (So, + * x.y.com domain-matches .Y.com but not Y.com.)</ul> + * </ol> + * + * @param host host name where cookie is received from or being sent to. + * @param domain The cookie domain attribute. + * @return true if the specified host matches the given domain. + */ + public boolean domainMatch(final String host, final String domain) { + final boolean match = host.equals(domain) + || (domain.startsWith(".") && host.endsWith(domain)); + + return match; + } + + /** + * Validate cookie domain attribute. + */ + public void validate(final Cookie cookie, final CookieOrigin origin) + throws MalformedCookieException { + Args.notNull(cookie, "Cookie"); + Args.notNull(origin, "Cookie origin"); + final String host = origin.getHost().toLowerCase(Locale.ENGLISH); + if (cookie.getDomain() == null) { + throw new CookieRestrictionViolationException("Invalid cookie state: " + + "domain not specified"); + } + final String cookieDomain = cookie.getDomain().toLowerCase(Locale.ENGLISH); + + if (cookie instanceof ClientCookie + && ((ClientCookie) cookie).containsAttribute(ClientCookie.DOMAIN_ATTR)) { + // Domain attribute must start with a dot + if (!cookieDomain.startsWith(".")) { + throw new CookieRestrictionViolationException("Domain attribute \"" + + cookie.getDomain() + "\" violates RFC 2109: domain must start with a dot"); + } + + // Domain attribute must contain at least one embedded dot, + // or the value must be equal to .local. + final int dotIndex = cookieDomain.indexOf('.', 1); + if (((dotIndex < 0) || (dotIndex == cookieDomain.length() - 1)) + && (!cookieDomain.equals(".local"))) { + throw new CookieRestrictionViolationException( + "Domain attribute \"" + cookie.getDomain() + + "\" violates RFC 2965: the value contains no embedded dots " + + "and the value is not .local"); + } + + // The effective host name must domain-match domain attribute. + if (!domainMatch(host, cookieDomain)) { + throw new CookieRestrictionViolationException( + "Domain attribute \"" + cookie.getDomain() + + "\" violates RFC 2965: effective host name does not " + + "domain-match domain attribute."); + } + + // effective host name minus domain must not contain any dots + final String effectiveHostWithoutDomain = host.substring( + 0, host.length() - cookieDomain.length()); + if (effectiveHostWithoutDomain.indexOf('.') != -1) { + throw new CookieRestrictionViolationException("Domain attribute \"" + + cookie.getDomain() + "\" violates RFC 2965: " + + "effective host minus domain may not contain any dots"); + } + } else { + // Domain was not specified in header. In this case, domain must + // string match request host (case-insensitive). + if (!cookie.getDomain().equals(host)) { + throw new CookieRestrictionViolationException("Illegal domain attribute: \"" + + cookie.getDomain() + "\"." + + "Domain of origin: \"" + + host + "\""); + } + } + } + + /** + * Match cookie domain attribute. + */ + public boolean match(final Cookie cookie, final CookieOrigin origin) { + Args.notNull(cookie, "Cookie"); + Args.notNull(origin, "Cookie origin"); + final String host = origin.getHost().toLowerCase(Locale.ENGLISH); + final String cookieDomain = cookie.getDomain(); + + // The effective host name MUST domain-match the Domain + // attribute of the cookie. + if (!domainMatch(host, cookieDomain)) { + return false; + } + // effective host name minus domain must not contain any dots + final String effectiveHostWithoutDomain = host.substring( + 0, host.length() - cookieDomain.length()); + return effectiveHostWithoutDomain.indexOf('.') == -1; + } + +} diff --git a/mobile/android/thirdparty/ch/boye/httpclientandroidlib/impl/cookie/RFC2965PortAttributeHandler.java b/mobile/android/thirdparty/ch/boye/httpclientandroidlib/impl/cookie/RFC2965PortAttributeHandler.java new file mode 100644 index 000000000..4835d8eb5 --- /dev/null +++ b/mobile/android/thirdparty/ch/boye/httpclientandroidlib/impl/cookie/RFC2965PortAttributeHandler.java @@ -0,0 +1,160 @@ +/* + * ==================================================================== + * 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. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * <http://www.apache.org/>. + * + */ + +package ch.boye.httpclientandroidlib.impl.cookie; + +import java.util.StringTokenizer; + +import ch.boye.httpclientandroidlib.annotation.Immutable; +import ch.boye.httpclientandroidlib.cookie.ClientCookie; +import ch.boye.httpclientandroidlib.cookie.Cookie; +import ch.boye.httpclientandroidlib.cookie.CookieAttributeHandler; +import ch.boye.httpclientandroidlib.cookie.CookieOrigin; +import ch.boye.httpclientandroidlib.cookie.CookieRestrictionViolationException; +import ch.boye.httpclientandroidlib.cookie.MalformedCookieException; +import ch.boye.httpclientandroidlib.cookie.SetCookie; +import ch.boye.httpclientandroidlib.cookie.SetCookie2; +import ch.boye.httpclientandroidlib.util.Args; + +/** + * <tt>"Port"</tt> cookie attribute handler for RFC 2965 cookie spec. + * + * @since 4.0 + */ +@Immutable +public class RFC2965PortAttributeHandler implements CookieAttributeHandler { + + public RFC2965PortAttributeHandler() { + super(); + } + + /** + * Parses the given Port attribute value (e.g. "8000,8001,8002") + * into an array of ports. + * + * @param portValue port attribute value + * @return parsed array of ports + * @throws MalformedCookieException if there is a problem in + * parsing due to invalid portValue. + */ + private static int[] parsePortAttribute(final String portValue) + throws MalformedCookieException { + final StringTokenizer st = new StringTokenizer(portValue, ","); + final int[] ports = new int[st.countTokens()]; + try { + int i = 0; + while(st.hasMoreTokens()) { + ports[i] = Integer.parseInt(st.nextToken().trim()); + if (ports[i] < 0) { + throw new MalformedCookieException ("Invalid Port attribute."); + } + ++i; + } + } catch (final NumberFormatException e) { + throw new MalformedCookieException ("Invalid Port " + + "attribute: " + e.getMessage()); + } + return ports; + } + + /** + * Returns <tt>true</tt> if the given port exists in the given + * ports list. + * + * @param port port of host where cookie was received from or being sent to. + * @param ports port list + * @return true returns <tt>true</tt> if the given port exists in + * the given ports list; <tt>false</tt> otherwise. + */ + private static boolean portMatch(final int port, final int[] ports) { + boolean portInList = false; + for (final int port2 : ports) { + if (port == port2) { + portInList = true; + break; + } + } + return portInList; + } + + /** + * Parse cookie port attribute. + */ + public void parse(final SetCookie cookie, final String portValue) + throws MalformedCookieException { + Args.notNull(cookie, "Cookie"); + if (cookie instanceof SetCookie2) { + final SetCookie2 cookie2 = (SetCookie2) cookie; + if (portValue != null && portValue.trim().length() > 0) { + final int[] ports = parsePortAttribute(portValue); + cookie2.setPorts(ports); + } + } + } + + /** + * Validate cookie port attribute. If the Port attribute was specified + * in header, the request port must be in cookie's port list. + */ + public void validate(final Cookie cookie, final CookieOrigin origin) + throws MalformedCookieException { + Args.notNull(cookie, "Cookie"); + Args.notNull(origin, "Cookie origin"); + final int port = origin.getPort(); + if (cookie instanceof ClientCookie + && ((ClientCookie) cookie).containsAttribute(ClientCookie.PORT_ATTR)) { + if (!portMatch(port, cookie.getPorts())) { + throw new CookieRestrictionViolationException( + "Port attribute violates RFC 2965: " + + "Request port not found in cookie's port list."); + } + } + } + + /** + * Match cookie port attribute. If the Port attribute is not specified + * in header, the cookie can be sent to any port. Otherwise, the request port + * must be in the cookie's port list. + */ + public boolean match(final Cookie cookie, final CookieOrigin origin) { + Args.notNull(cookie, "Cookie"); + Args.notNull(origin, "Cookie origin"); + final int port = origin.getPort(); + if (cookie instanceof ClientCookie + && ((ClientCookie) cookie).containsAttribute(ClientCookie.PORT_ATTR)) { + if (cookie.getPorts() == null) { + // Invalid cookie state: port not specified + return false; + } + if (!portMatch(port, cookie.getPorts())) { + return false; + } + } + return true; + } + +} diff --git a/mobile/android/thirdparty/ch/boye/httpclientandroidlib/impl/cookie/RFC2965Spec.java b/mobile/android/thirdparty/ch/boye/httpclientandroidlib/impl/cookie/RFC2965Spec.java new file mode 100644 index 000000000..1c0dbc4cb --- /dev/null +++ b/mobile/android/thirdparty/ch/boye/httpclientandroidlib/impl/cookie/RFC2965Spec.java @@ -0,0 +1,239 @@ +/* + * ==================================================================== + * 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. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * <http://www.apache.org/>. + * + */ +package ch.boye.httpclientandroidlib.impl.cookie; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Locale; +import java.util.Map; + +import ch.boye.httpclientandroidlib.Header; +import ch.boye.httpclientandroidlib.HeaderElement; +import ch.boye.httpclientandroidlib.NameValuePair; +import ch.boye.httpclientandroidlib.annotation.NotThreadSafe; +import ch.boye.httpclientandroidlib.cookie.ClientCookie; +import ch.boye.httpclientandroidlib.cookie.Cookie; +import ch.boye.httpclientandroidlib.cookie.CookieAttributeHandler; +import ch.boye.httpclientandroidlib.cookie.CookieOrigin; +import ch.boye.httpclientandroidlib.cookie.MalformedCookieException; +import ch.boye.httpclientandroidlib.cookie.SM; +import ch.boye.httpclientandroidlib.message.BufferedHeader; +import ch.boye.httpclientandroidlib.util.Args; +import ch.boye.httpclientandroidlib.util.CharArrayBuffer; + +/** + * RFC 2965 compliant {@link ch.boye.httpclientandroidlib.cookie.CookieSpec} implementation. + * + * @since 4.0 + */ +@NotThreadSafe // superclass is @NotThreadSafe +public class RFC2965Spec extends RFC2109Spec { + + /** + * Default constructor + * + */ + public RFC2965Spec() { + this(null, false); + } + + public RFC2965Spec(final String[] datepatterns, final boolean oneHeader) { + super(datepatterns, oneHeader); + registerAttribHandler(ClientCookie.DOMAIN_ATTR, new RFC2965DomainAttributeHandler()); + registerAttribHandler(ClientCookie.PORT_ATTR, new RFC2965PortAttributeHandler()); + registerAttribHandler(ClientCookie.COMMENTURL_ATTR, new RFC2965CommentUrlAttributeHandler()); + registerAttribHandler(ClientCookie.DISCARD_ATTR, new RFC2965DiscardAttributeHandler()); + registerAttribHandler(ClientCookie.VERSION_ATTR, new RFC2965VersionAttributeHandler()); + } + + @Override + public List<Cookie> parse( + final Header header, + final CookieOrigin origin) throws MalformedCookieException { + Args.notNull(header, "Header"); + Args.notNull(origin, "Cookie origin"); + if (!header.getName().equalsIgnoreCase(SM.SET_COOKIE2)) { + throw new MalformedCookieException("Unrecognized cookie header '" + + header.toString() + "'"); + } + final HeaderElement[] elems = header.getElements(); + return createCookies(elems, adjustEffectiveHost(origin)); + } + + @Override + protected List<Cookie> parse( + final HeaderElement[] elems, + final CookieOrigin origin) throws MalformedCookieException { + return createCookies(elems, adjustEffectiveHost(origin)); + } + + private List<Cookie> createCookies( + final HeaderElement[] elems, + final CookieOrigin origin) throws MalformedCookieException { + final List<Cookie> cookies = new ArrayList<Cookie>(elems.length); + for (final HeaderElement headerelement : elems) { + final String name = headerelement.getName(); + final String value = headerelement.getValue(); + if (name == null || name.length() == 0) { + throw new MalformedCookieException("Cookie name may not be empty"); + } + + final BasicClientCookie2 cookie = new BasicClientCookie2(name, value); + cookie.setPath(getDefaultPath(origin)); + cookie.setDomain(getDefaultDomain(origin)); + cookie.setPorts(new int [] { origin.getPort() }); + // cycle through the parameters + final NameValuePair[] attribs = headerelement.getParameters(); + + // Eliminate duplicate attributes. The first occurrence takes precedence + // See RFC2965: 3.2 Origin Server Role + final Map<String, NameValuePair> attribmap = + new HashMap<String, NameValuePair>(attribs.length); + for (int j = attribs.length - 1; j >= 0; j--) { + final NameValuePair param = attribs[j]; + attribmap.put(param.getName().toLowerCase(Locale.ENGLISH), param); + } + for (final Map.Entry<String, NameValuePair> entry : attribmap.entrySet()) { + final NameValuePair attrib = entry.getValue(); + final String s = attrib.getName().toLowerCase(Locale.ENGLISH); + + cookie.setAttribute(s, attrib.getValue()); + + final CookieAttributeHandler handler = findAttribHandler(s); + if (handler != null) { + handler.parse(cookie, attrib.getValue()); + } + } + cookies.add(cookie); + } + return cookies; + } + + @Override + public void validate( + final Cookie cookie, final CookieOrigin origin) throws MalformedCookieException { + Args.notNull(cookie, "Cookie"); + Args.notNull(origin, "Cookie origin"); + super.validate(cookie, adjustEffectiveHost(origin)); + } + + @Override + public boolean match(final Cookie cookie, final CookieOrigin origin) { + Args.notNull(cookie, "Cookie"); + Args.notNull(origin, "Cookie origin"); + return super.match(cookie, adjustEffectiveHost(origin)); + } + + /** + * Adds valid Port attribute value, e.g. "8000,8001,8002" + */ + @Override + protected void formatCookieAsVer(final CharArrayBuffer buffer, + final Cookie cookie, final int version) { + super.formatCookieAsVer(buffer, cookie, version); + // format port attribute + if (cookie instanceof ClientCookie) { + // Test if the port attribute as set by the origin server is not blank + final String s = ((ClientCookie) cookie).getAttribute(ClientCookie.PORT_ATTR); + if (s != null) { + buffer.append("; $Port"); + buffer.append("=\""); + if (s.trim().length() > 0) { + final int[] ports = cookie.getPorts(); + if (ports != null) { + final int len = ports.length; + for (int i = 0; i < len; i++) { + if (i > 0) { + buffer.append(","); + } + buffer.append(Integer.toString(ports[i])); + } + } + } + buffer.append("\""); + } + } + } + + /** + * Set 'effective host name' as defined in RFC 2965. + * <p> + * If a host name contains no dots, the effective host name is + * that name with the string .local appended to it. Otherwise + * the effective host name is the same as the host name. Note + * that all effective host names contain at least one dot. + * + * @param origin origin where cookie is received from or being sent to. + */ + private static CookieOrigin adjustEffectiveHost(final CookieOrigin origin) { + String host = origin.getHost(); + + // Test if the host name appears to be a fully qualified DNS name, + // IPv4 address or IPv6 address + boolean isLocalHost = true; + for (int i = 0; i < host.length(); i++) { + final char ch = host.charAt(i); + if (ch == '.' || ch == ':') { + isLocalHost = false; + break; + } + } + if (isLocalHost) { + host += ".local"; + return new CookieOrigin( + host, + origin.getPort(), + origin.getPath(), + origin.isSecure()); + } else { + return origin; + } + } + + @Override + public int getVersion() { + return 1; + } + + @Override + public Header getVersionHeader() { + final CharArrayBuffer buffer = new CharArrayBuffer(40); + buffer.append(SM.COOKIE2); + buffer.append(": "); + buffer.append("$Version="); + buffer.append(Integer.toString(getVersion())); + return new BufferedHeader(buffer); + } + + @Override + public String toString() { + return "rfc2965"; + } + +} + diff --git a/mobile/android/thirdparty/ch/boye/httpclientandroidlib/impl/cookie/RFC2965SpecFactory.java b/mobile/android/thirdparty/ch/boye/httpclientandroidlib/impl/cookie/RFC2965SpecFactory.java new file mode 100644 index 000000000..83b60407c --- /dev/null +++ b/mobile/android/thirdparty/ch/boye/httpclientandroidlib/impl/cookie/RFC2965SpecFactory.java @@ -0,0 +1,86 @@ +/* + * ==================================================================== + * 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. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * <http://www.apache.org/>. + * + */ + +package ch.boye.httpclientandroidlib.impl.cookie; + +import java.util.Collection; + +import ch.boye.httpclientandroidlib.annotation.Immutable; +import ch.boye.httpclientandroidlib.cookie.CookieSpec; +import ch.boye.httpclientandroidlib.cookie.CookieSpecFactory; +import ch.boye.httpclientandroidlib.cookie.CookieSpecProvider; +import ch.boye.httpclientandroidlib.cookie.params.CookieSpecPNames; +import ch.boye.httpclientandroidlib.params.HttpParams; +import ch.boye.httpclientandroidlib.protocol.HttpContext; + +/** + * {@link CookieSpecProvider} implementation that creates and initializes + * {@link RFC2965Spec} instances. + * + * @since 4.0 + */ +@Immutable +@SuppressWarnings("deprecation") +public class RFC2965SpecFactory implements CookieSpecFactory, CookieSpecProvider { + + private final String[] datepatterns; + private final boolean oneHeader; + + public RFC2965SpecFactory(final String[] datepatterns, final boolean oneHeader) { + super(); + this.datepatterns = datepatterns; + this.oneHeader = oneHeader; + } + + public RFC2965SpecFactory() { + this(null, false); + } + + public CookieSpec newInstance(final HttpParams params) { + if (params != null) { + + String[] patterns = null; + final Collection<?> param = (Collection<?>) params.getParameter( + CookieSpecPNames.DATE_PATTERNS); + if (param != null) { + patterns = new String[param.size()]; + patterns = param.toArray(patterns); + } + final boolean singleHeader = params.getBooleanParameter( + CookieSpecPNames.SINGLE_COOKIE_HEADER, false); + + return new RFC2965Spec(patterns, singleHeader); + } else { + return new RFC2965Spec(); + } + } + + public CookieSpec create(final HttpContext context) { + return new RFC2965Spec(this.datepatterns, this.oneHeader); + } + +} diff --git a/mobile/android/thirdparty/ch/boye/httpclientandroidlib/impl/cookie/RFC2965VersionAttributeHandler.java b/mobile/android/thirdparty/ch/boye/httpclientandroidlib/impl/cookie/RFC2965VersionAttributeHandler.java new file mode 100644 index 000000000..26ae4faa6 --- /dev/null +++ b/mobile/android/thirdparty/ch/boye/httpclientandroidlib/impl/cookie/RFC2965VersionAttributeHandler.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. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * <http://www.apache.org/>. + * + */ + +package ch.boye.httpclientandroidlib.impl.cookie; + +import ch.boye.httpclientandroidlib.annotation.Immutable; +import ch.boye.httpclientandroidlib.cookie.ClientCookie; +import ch.boye.httpclientandroidlib.cookie.Cookie; +import ch.boye.httpclientandroidlib.cookie.CookieAttributeHandler; +import ch.boye.httpclientandroidlib.cookie.CookieOrigin; +import ch.boye.httpclientandroidlib.cookie.CookieRestrictionViolationException; +import ch.boye.httpclientandroidlib.cookie.MalformedCookieException; +import ch.boye.httpclientandroidlib.cookie.SetCookie; +import ch.boye.httpclientandroidlib.cookie.SetCookie2; +import ch.boye.httpclientandroidlib.util.Args; + +/** + * <tt>"Version"</tt> cookie attribute handler for RFC 2965 cookie spec. + * + * @since 4.0 + */ +@Immutable +public class RFC2965VersionAttributeHandler implements CookieAttributeHandler { + + public RFC2965VersionAttributeHandler() { + super(); + } + + /** + * Parse cookie version attribute. + */ + public void parse(final SetCookie cookie, final String value) + throws MalformedCookieException { + Args.notNull(cookie, "Cookie"); + if (value == null) { + throw new MalformedCookieException( + "Missing value for version attribute"); + } + int version = -1; + try { + version = Integer.parseInt(value); + } catch (final NumberFormatException e) { + version = -1; + } + if (version < 0) { + throw new MalformedCookieException("Invalid cookie version."); + } + cookie.setVersion(version); + } + + /** + * validate cookie version attribute. Version attribute is REQUIRED. + */ + public void validate(final Cookie cookie, final CookieOrigin origin) + throws MalformedCookieException { + Args.notNull(cookie, "Cookie"); + if (cookie instanceof SetCookie2) { + if (cookie instanceof ClientCookie + && !((ClientCookie) cookie).containsAttribute(ClientCookie.VERSION_ATTR)) { + throw new CookieRestrictionViolationException( + "Violates RFC 2965. Version attribute is required."); + } + } + } + + public boolean match(final Cookie cookie, final CookieOrigin origin) { + return true; + } + +} diff --git a/mobile/android/thirdparty/ch/boye/httpclientandroidlib/impl/cookie/package-info.java b/mobile/android/thirdparty/ch/boye/httpclientandroidlib/impl/cookie/package-info.java new file mode 100644 index 000000000..1950e7263 --- /dev/null +++ b/mobile/android/thirdparty/ch/boye/httpclientandroidlib/impl/cookie/package-info.java @@ -0,0 +1,32 @@ +/* + * ==================================================================== + * 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. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * <http://www.apache.org/>. + * + */ + +/** + * Default implementations of standard and common HTTP state + * management policies. + */ +package ch.boye.httpclientandroidlib.impl.cookie; |