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  
28  package org.apache.http.conn;
29  
30  import java.io.IOException;
31  import java.net.InetAddress;
32  import java.net.InetSocketAddress;
33  import java.net.Socket;
34  import java.net.SocketTimeoutException;
35  import java.util.ArrayList;
36  import java.util.Arrays;
37  import java.util.Collections;
38  import java.util.List;
39  
40  import org.apache.http.annotation.Immutable;
41  import org.apache.http.conn.scheme.SocketFactory;
42  import org.apache.http.params.HttpConnectionParams;
43  import org.apache.http.params.HttpParams;
44  import org.apache.http.util.Args;
45  import org.apache.http.util.Asserts;
46  
47  /**
48   * Socket factory that implements a simple multi-home fail-over on connect failure,
49   * provided the same hostname resolves to multiple {@link InetAddress}es. Please note
50   * the {@link #connectSocket(Socket, String, int, InetAddress, int, HttpParams)}
51   * method cannot be reliably interrupted by closing the socket returned by the
52   * {@link #createSocket()} method.
53   *
54   * @since 4.0
55   *
56   * @deprecated (4.1)  Do not use. For multihome support socket factories must implement
57   * {@link org.apache.http.conn.scheme.SchemeSocketFactory} interface.
58   */
59  @Deprecated
60  @Immutable
61  public final class MultihomePlainSocketFactory implements SocketFactory {
62  
63      /**
64       * The factory singleton.
65       */
66      private static final
67      MultihomePlainSocketFactory DEFAULT_FACTORY = new MultihomePlainSocketFactory();
68  
69      /**
70       * Gets the singleton instance of this class.
71       * @return the one and only plain socket factory
72       */
73      public static MultihomePlainSocketFactory getSocketFactory() {
74          return DEFAULT_FACTORY;
75      }
76  
77      /**
78       * Restricted default constructor.
79       */
80      private MultihomePlainSocketFactory() {
81          super();
82      }
83  
84  
85      // non-javadoc, see interface org.apache.http.conn.SocketFactory
86      public Socket createSocket() {
87          return new Socket();
88      }
89  
90      /**
91       * Attempts to connects the socket to any of the {@link InetAddress}es the
92       * given host name resolves to. If connection to all addresses fail, the
93       * last I/O exception is propagated to the caller.
94       *
95       * @param socket socket to connect to any of the given addresses
96       * @param host Host name to connect to
97       * @param port the port to connect to
98       * @param localAddress local address
99       * @param localPort local port
100      * @param params HTTP parameters
101      *
102      * @throws  IOException if an error occurs during the connection
103      * @throws  SocketTimeoutException if timeout expires before connecting
104      */
105     public Socket connectSocket(final Socket socket, final String host, final int port,
106                                 final InetAddress localAddress, final int localPort,
107                                 final HttpParams params)
108         throws IOException {
109         Args.notNull(host, "Target host");
110         Args.notNull(params, "HTTP parameters");
111 
112         Socket sock = socket;
113         if (sock == null) {
114             sock = createSocket();
115         }
116 
117         if ((localAddress != null) || (localPort > 0)) {
118             final InetSocketAddress isa = new InetSocketAddress(localAddress,
119                     localPort > 0 ? localPort : 0);
120             sock.bind(isa);
121         }
122 
123         final int timeout = HttpConnectionParams.getConnectionTimeout(params);
124 
125         final InetAddress[] inetadrs = InetAddress.getAllByName(host);
126         final List<InetAddress> addresses = new ArrayList<InetAddress>(inetadrs.length);
127         addresses.addAll(Arrays.asList(inetadrs));
128         Collections.shuffle(addresses);
129 
130         IOException lastEx = null;
131         for (final InetAddress remoteAddress: addresses) {
132             try {
133                 sock.connect(new InetSocketAddress(remoteAddress, port), timeout);
134                 break;
135             } catch (final SocketTimeoutException ex) {
136                 throw new ConnectTimeoutException("Connect to " + remoteAddress + " timed out");
137             } catch (final IOException ex) {
138                 // create new socket
139                 sock = new Socket();
140                 // keep the last exception and retry
141                 lastEx = ex;
142             }
143         }
144         if (lastEx != null) {
145             throw lastEx;
146         }
147         return sock;
148     } // connectSocket
149 
150 
151     /**
152      * Checks whether a socket connection is secure.
153      * This factory creates plain socket connections
154      * which are not considered secure.
155      *
156      * @param sock      the connected socket
157      *
158      * @return  {@code false}
159      *
160      * @throws IllegalArgumentException if the argument is invalid
161      */
162     public final boolean isSecure(final Socket sock)
163         throws IllegalArgumentException {
164 
165         Args.notNull(sock, "Socket");
166         // This check is performed last since it calls a method implemented
167         // by the argument object. getClass() is final in java.lang.Object.
168         Asserts.check(!sock.isClosed(), "Socket is closed");
169         return false;
170 
171     } // isSecure
172 
173 }