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.ThreadSafe;
42  import org.apache.http.auth.AuthScheme;
43  import org.apache.http.client.AuthCache;
44  import org.apache.http.conn.SchemePortResolver;
45  import org.apache.http.conn.UnsupportedSchemeException;
46  import org.apache.http.impl.conn.DefaultSchemePortResolver;
47  import org.apache.http.util.Args;
48  
49  /**
50   * Default implementation of {@link org.apache.http.client.AuthCache}. This implements
51   * expects {@link org.apache.http.auth.AuthScheme} to be {@link java.io.Serializable}
52   * in order to be cacheable.
53   * <p>
54   * Instances of this class are thread safe as of version 4.4.
55   * </p>
56   *
57   * @since 4.1
58   */
59  @ThreadSafe
60  public class BasicAuthCache implements AuthCache {
61  
62      private final Log log = LogFactory.getLog(getClass());
63  
64      private final Map<HttpHost, byte[]> map;
65      private final SchemePortResolver schemePortResolver;
66  
67      /**
68       * Default constructor.
69       *
70       * @since 4.3
71       */
72      public BasicAuthCache(final SchemePortResolver schemePortResolver) {
73          super();
74          this.map = new ConcurrentHashMap<HttpHost, byte[]>();
75          this.schemePortResolver = schemePortResolver != null ? schemePortResolver :
76              DefaultSchemePortResolver.INSTANCE;
77      }
78  
79      public BasicAuthCache() {
80          this(null);
81      }
82  
83      protected HttpHost getKey(final HttpHost host) {
84          if (host.getPort() <= 0) {
85              final int port;
86              try {
87                  port = schemePortResolver.resolve(host);
88              } catch (final UnsupportedSchemeException ignore) {
89                  return host;
90              }
91              return new HttpHost(host.getHostName(), port, host.getSchemeName());
92          } else {
93              return host;
94          }
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 (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 authScheme = (AuthScheme) in.readObject();
131                 in.close();
132                 return authScheme;
133             } catch (IOException ex) {
134                 if (log.isWarnEnabled()) {
135                     log.warn("Unexpected I/O error while de-serializing auth scheme", ex);
136                 }
137                 return null;
138             } catch (ClassNotFoundException ex) {
139                 if (log.isWarnEnabled()) {
140                     log.warn("Unexpected error while de-serializing auth scheme", ex);
141                 }
142                 return null;
143             }
144         } else {
145             return null;
146         }
147     }
148 
149     @Override
150     public void remove(final HttpHost host) {
151         Args.notNull(host, "HTTP host");
152         this.map.remove(getKey(host));
153     }
154 
155     @Override
156     public void clear() {
157         this.map.clear();
158     }
159 
160     @Override
161     public String toString() {
162         return this.map.toString();
163     }
164 
165 }