001/* 002 * ==================================================================== 003 * Licensed to the Apache Software Foundation (ASF) under one 004 * or more contributor license agreements. See the NOTICE file 005 * distributed with this work for additional information 006 * regarding copyright ownership. The ASF licenses this file 007 * to you under the Apache License, Version 2.0 (the 008 * "License"); you may not use this file except in compliance 009 * with the License. You may obtain a copy of the License at 010 * 011 * http://www.apache.org/licenses/LICENSE-2.0 012 * 013 * Unless required by applicable law or agreed to in writing, 014 * software distributed under the License is distributed on an 015 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 016 * KIND, either express or implied. See the License for the 017 * specific language governing permissions and limitations 018 * under the License. 019 * ==================================================================== 020 * 021 * This software consists of voluntary contributions made by many 022 * individuals on behalf of the Apache Software Foundation. For more 023 * information on the Apache Software Foundation, please see 024 * <http://www.apache.org/>. 025 * 026 */ 027 028package org.apache.http.impl.cookie; 029 030import org.apache.http.annotation.Contract; 031import org.apache.http.annotation.ThreadingBehavior; 032import org.apache.http.conn.util.PublicSuffixMatcher; 033import org.apache.http.cookie.Cookie; 034import org.apache.http.cookie.CookieOrigin; 035import org.apache.http.cookie.CookieSpec; 036import org.apache.http.cookie.CookieSpecProvider; 037import org.apache.http.cookie.MalformedCookieException; 038import org.apache.http.protocol.HttpContext; 039 040/** 041 * {@link org.apache.http.cookie.CookieSpecProvider} implementation that provides an instance of 042 * RFC 6265 conformant cookie policy. The instance returned by this factory can be shared by 043 * multiple threads. 044 * 045 * @since 4.4 046 */ 047@Contract(threading = ThreadingBehavior.IMMUTABLE_CONDITIONAL) 048public class RFC6265CookieSpecProvider implements CookieSpecProvider { 049 050 public enum CompatibilityLevel { 051 STRICT, 052 RELAXED, 053 IE_MEDIUM_SECURITY 054 } 055 056 private final CompatibilityLevel compatibilityLevel; 057 private final PublicSuffixMatcher publicSuffixMatcher; 058 059 private volatile CookieSpec cookieSpec; 060 061 public RFC6265CookieSpecProvider( 062 final CompatibilityLevel compatibilityLevel, 063 final PublicSuffixMatcher publicSuffixMatcher) { 064 super(); 065 this.compatibilityLevel = compatibilityLevel != null ? compatibilityLevel : CompatibilityLevel.RELAXED; 066 this.publicSuffixMatcher = publicSuffixMatcher; 067 } 068 069 public RFC6265CookieSpecProvider(final PublicSuffixMatcher publicSuffixMatcher) { 070 this(CompatibilityLevel.RELAXED, publicSuffixMatcher); 071 } 072 073 public RFC6265CookieSpecProvider() { 074 this(CompatibilityLevel.RELAXED, null); 075 } 076 077 @Override 078 public CookieSpec create(final HttpContext context) { 079 if (cookieSpec == null) { 080 synchronized (this) { 081 if (cookieSpec == null) { 082 switch (this.compatibilityLevel) { 083 case STRICT: 084 this.cookieSpec = new RFC6265StrictSpec( 085 new BasicPathHandler(), 086 PublicSuffixDomainFilter.decorate( 087 new BasicDomainHandler(), this.publicSuffixMatcher), 088 new BasicMaxAgeHandler(), 089 new BasicSecureHandler(), 090 new BasicExpiresHandler(RFC6265StrictSpec.DATE_PATTERNS)); 091 break; 092 case IE_MEDIUM_SECURITY: 093 this.cookieSpec = new RFC6265LaxSpec( 094 new BasicPathHandler() { 095 @Override 096 public void validate( 097 final Cookie cookie, 098 final CookieOrigin origin) throws MalformedCookieException { 099 // No validation 100 } 101 }, 102 PublicSuffixDomainFilter.decorate( 103 new BasicDomainHandler(), this.publicSuffixMatcher), 104 new BasicMaxAgeHandler(), 105 new BasicSecureHandler(), 106 new BasicExpiresHandler(RFC6265StrictSpec.DATE_PATTERNS)); 107 break; 108 default: 109 this.cookieSpec = new RFC6265LaxSpec( 110 new BasicPathHandler(), 111 PublicSuffixDomainFilter.decorate( 112 new BasicDomainHandler(), this.publicSuffixMatcher), 113 new LaxMaxAgeHandler(), 114 new BasicSecureHandler(), 115 new LaxExpiresHandler()); 116 } 117 } 118 } 119 } 120 return this.cookieSpec; 121 } 122 123}