View Javadoc
1   /*
2    * ====================================================================
3    * Licensed to the Apache Software Foundation (ASF) under one
4    * or more contributor license agreements.  See the NOTICE file
5    * distributed with this work for additional information
6    * regarding copyright ownership.  The ASF licenses this file
7    * to you under the Apache License, Version 2.0 (the
8    * "License"); you may not use this file except in compliance
9    * with the License.  You may obtain a copy of the License at
10   *
11   *   http://www.apache.org/licenses/LICENSE-2.0
12   *
13   * Unless required by applicable law or agreed to in writing,
14   * software distributed under the License is distributed on an
15   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16   * KIND, either express or implied.  See the License for the
17   * specific language governing permissions and limitations
18   * under the License.
19   * ====================================================================
20   *
21   * This software consists of voluntary contributions made by many
22   * individuals on behalf of the Apache Software Foundation.  For more
23   * information on the Apache Software Foundation, please see
24   * <http://www.apache.org/>.
25   *
26   */
27  package org.apache.http.impl.client;
28  
29  import java.io.ByteArrayInputStream;
30  import java.io.ByteArrayOutputStream;
31  import java.io.IOException;
32  import java.io.ObjectInputStream;
33  import java.io.ObjectOutputStream;
34  import java.io.Serializable;
35  import java.util.Map;
36  import java.util.concurrent.ConcurrentHashMap;
37  
38  import org.apache.commons.logging.Log;
39  import org.apache.commons.logging.LogFactory;
40  import org.apache.http.HttpHost;
41  import org.apache.http.annotation.Contract;
42  import org.apache.http.annotation.ThreadingBehavior;
43  import org.apache.http.auth.AuthScheme;
44  import org.apache.http.client.AuthCache;
45  import org.apache.http.conn.SchemePortResolver;
46  import org.apache.http.conn.UnsupportedSchemeException;
47  import org.apache.http.impl.conn.DefaultSchemePortResolver;
48  import org.apache.http.util.Args;
49  
50  /**
51   * Default implementation of {@link org.apache.http.client.AuthCache}. This implements
52   * expects {@link org.apache.http.auth.AuthScheme} to be {@link java.io.Serializable}
53   * in order to be cacheable.
54   * <p>
55   * Instances of this class are thread safe as of version 4.4.
56   * </p>
57   *
58   * @since 4.1
59   */
60  @Contract(threading = ThreadingBehavior.SAFE)
61  public class BasicAuthCache implements AuthCache {
62  
63      private final Log log = LogFactory.getLog(getClass());
64  
65      private final Map<HttpHost, byte[]> map;
66      private final SchemePortResolver schemePortResolver;
67  
68      /**
69       * Default constructor.
70       *
71       * @since 4.3
72       */
73      public BasicAuthCache(final SchemePortResolver schemePortResolver) {
74          super();
75          this.map = new ConcurrentHashMap<HttpHost, byte[]>();
76          this.schemePortResolver = schemePortResolver != null ? schemePortResolver :
77              DefaultSchemePortResolver.INSTANCE;
78      }
79  
80      public BasicAuthCache() {
81          this(null);
82      }
83  
84      protected HttpHost getKey(final HttpHost host) {
85          if (host.getPort() <= 0) {
86              final int port;
87              try {
88                  port = schemePortResolver.resolve(host);
89              } catch (final UnsupportedSchemeException ignore) {
90                  return host;
91              }
92              return new HttpHost(host.getHostName(), port, host.getSchemeName());
93          }
94          return host;
95      }
96  
97      @Override
98      public void put(final HttpHost host, final AuthScheme authScheme) {
99          Args.notNull(host, "HTTP host");
100         if (authScheme == null) {
101             return;
102         }
103         if (authScheme instanceof Serializable) {
104             try {
105                 final ByteArrayOutputStream buf = new ByteArrayOutputStream();
106                 final ObjectOutputStream out = new ObjectOutputStream(buf);
107                 out.writeObject(authScheme);
108                 out.close();
109                 this.map.put(getKey(host), buf.toByteArray());
110             } catch (final IOException ex) {
111                 if (log.isWarnEnabled()) {
112                     log.warn("Unexpected I/O error while serializing auth scheme", ex);
113                 }
114             }
115         } else {
116             if (log.isDebugEnabled()) {
117                 log.debug("Auth scheme " + authScheme.getClass() + " is not serializable");
118             }
119         }
120     }
121 
122     @Override
123     public AuthScheme get(final HttpHost host) {
124         Args.notNull(host, "HTTP host");
125         final byte[] bytes = this.map.get(getKey(host));
126         if (bytes != null) {
127             try {
128                 final ByteArrayInputStream buf = new ByteArrayInputStream(bytes);
129                 final ObjectInputStream in = new ObjectInputStream(buf);
130                 final AuthScheme/../../org/apache/http/auth/AuthScheme.html#AuthScheme">AuthScheme authScheme = (AuthScheme) in.readObject();
131                 in.close();
132                 return authScheme;
133             } catch (final IOException ex) {
134                 if (log.isWarnEnabled()) {
135                     log.warn("Unexpected I/O error while de-serializing auth scheme", ex);
136                 }
137             } catch (final ClassNotFoundException ex) {
138                 if (log.isWarnEnabled()) {
139                     log.warn("Unexpected error while de-serializing auth scheme", ex);
140                 }
141             }
142         }
143         return null;
144     }
145 
146     @Override
147     public void remove(final HttpHost host) {
148         Args.notNull(host, "HTTP host");
149         this.map.remove(getKey(host));
150     }
151 
152     @Override
153     public void clear() {
154         this.map.clear();
155     }
156 
157     @Override
158     public String toString() {
159         return this.map.toString();
160     }
161 
162 }