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   *
56   * @since 4.1
57   */
58  @ThreadSafe
59  public class BasicAuthCache implements AuthCache {
60  
61      private final Log log = LogFactory.getLog(getClass());
62  
63      private final Map<HttpHost, byte[]> map;
64      private final SchemePortResolver schemePortResolver;
65  
66      /**
67       * Default constructor.
68       *
69       * @since 4.3
70       */
71      public BasicAuthCache(final SchemePortResolver schemePortResolver) {
72          super();
73          this.map = new ConcurrentHashMap<HttpHost, byte[]>();
74          this.schemePortResolver = schemePortResolver != null ? schemePortResolver :
75              DefaultSchemePortResolver.INSTANCE;
76      }
77  
78      public BasicAuthCache() {
79          this(null);
80      }
81  
82      protected HttpHost getKey(final HttpHost host) {
83          if (host.getPort() <= 0) {
84              final int port;
85              try {
86                  port = schemePortResolver.resolve(host);
87              } catch (final UnsupportedSchemeException ignore) {
88                  return host;
89              }
90              return new HttpHost(host.getHostName(), port, host.getSchemeName());
91          } else {
92              return host;
93          }
94      }
95  
96      @Override
97      public void put(final HttpHost host, final AuthScheme authScheme) {
98          Args.notNull(host, "HTTP host");
99          if (authScheme == null) {
100             return;
101         }
102         if (authScheme instanceof Serializable) {
103             try {
104                 final ByteArrayOutputStream buf = new ByteArrayOutputStream();
105                 final ObjectOutputStream out = new ObjectOutputStream(buf);
106                 out.writeObject(authScheme);
107                 out.close();
108                 this.map.put(getKey(host), buf.toByteArray());
109             } catch (IOException ex) {
110                 if (log.isWarnEnabled()) {
111                     log.warn("Unexpected I/O error while serializing auth scheme", ex);
112                 }
113             }
114         } else {
115             if (log.isDebugEnabled()) {
116                 log.debug("Auth scheme " + authScheme.getClass() + " is not serializable");
117             }
118         }
119     }
120 
121     @Override
122     public AuthScheme get(final HttpHost host) {
123         Args.notNull(host, "HTTP host");
124         final byte[] bytes = this.map.get(getKey(host));
125         if (bytes != null) {
126             try {
127                 final ByteArrayInputStream buf = new ByteArrayInputStream(bytes);
128                 final ObjectInputStream in = new ObjectInputStream(buf);
129                 final AuthScheme authScheme = (AuthScheme) in.readObject();
130                 in.close();
131                 return authScheme;
132             } catch (IOException ex) {
133                 if (log.isWarnEnabled()) {
134                     log.warn("Unexpected I/O error while de-serializing auth scheme", ex);
135                 }
136                 return null;
137             } catch (ClassNotFoundException ex) {
138                 if (log.isWarnEnabled()) {
139                     log.warn("Unexpected error while de-serializing auth scheme", ex);
140                 }
141                 return null;
142             }
143         } else {
144             return null;
145         }
146     }
147 
148     @Override
149     public void remove(final HttpHost host) {
150         Args.notNull(host, "HTTP host");
151         this.map.remove(getKey(host));
152     }
153 
154     @Override
155     public void clear() {
156         this.map.clear();
157     }
158 
159     @Override
160     public String toString() {
161         return this.map.toString();
162     }
163 
164 }