View Javadoc
1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one or more
3    * contributor license agreements.  See the NOTICE file distributed with
4    * this work for additional information regarding copyright ownership.
5    * The ASF licenses this file to You under the Apache License, Version 2.0
6    * (the "License"); you may not use this file except in compliance with
7    * the License.  You may obtain a copy of the License at
8    *
9    *      http://www.apache.org/licenses/LICENSE-2.0
10   *
11   * Unless required by applicable law or agreed to in writing, software
12   * distributed under the License is distributed on an "AS IS" BASIS,
13   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14   * See the License for the specific language governing permissions and
15   * limitations under the License.
16   */
17  package org.apache.commons.net.finger;
18  
19  import java.io.BufferedOutputStream;
20  import java.io.BufferedReader;
21  import java.io.DataOutputStream;
22  import java.io.IOException;
23  import java.io.InputStream;
24  import java.io.InputStreamReader;
25  
26  import org.apache.commons.net.SocketClient;
27  import org.apache.commons.net.util.Charsets;
28  
29  /**
30   * The FingerClient class implements the client side of the Internet Finger Protocol defined in RFC 1288. To finger a host you create a FingerClient instance,
31   * connect to the host, query the host, and finally disconnect from the host. If the finger service you want to query is on a non-standard port, connect to the
32   * host at that port. Here's a sample use:
33   *
34   * <pre>
35   * FingerClient finger;
36   *
37   * finger = new FingerClient();
38   *
39   * try {
40   *     finger.connect("foo.bar.com");
41   *     System.out.println(finger.query("foobar", false));
42   *     finger.disconnect();
43   * } catch (IOException e) {
44   *     System.err.println("Error I/O exception: " + e.getMessage());
45   *     return;
46   * }
47   * </pre>
48   */
49  
50  public class FingerClient extends SocketClient {
51      /**
52       * The default FINGER port. Set to 79 according to RFC 1288.
53       */
54      public static final int DEFAULT_PORT = 79;
55  
56      private static final String LONG_FLAG = "/W ";
57  
58      private final transient char[] buffer = new char[1024];
59  
60      /**
61       * The default FingerClient constructor. Initializes the default port to <code>DEFAULT_PORT</code>.
62       */
63      public FingerClient() {
64          setDefaultPort(DEFAULT_PORT);
65      }
66  
67      /**
68       * Fingers the connected host and returns the input stream from the network connection of the finger query. This is equivalent to calling
69       * getInputStream(longOutput, ""). You must first connect to a finger server before calling this method, and you should disconnect after finishing reading
70       * the stream.
71       *
72       * @param longOutput Set to true if long output is requested, false if not.
73       * @return The InputStream of the network connection of the finger query. Can be read to obtain finger results.
74       * @throws IOException If an I/O error during the operation.
75       */
76      public InputStream getInputStream(final boolean longOutput) throws IOException {
77          return getInputStream(longOutput, "");
78      }
79  
80      /**
81       * Fingers a user and returns the input stream from the network connection of the finger query. You must first connect to a finger server before calling
82       * this method, and you should disconnect after finishing reading the stream.
83       *
84       * @param longOutput Set to true if long output is requested, false if not.
85       * @param user   The name of the user to finger.
86       * @return The InputStream of the network connection of the finger query. Can be read to obtain finger results.
87       * @throws IOException If an I/O error during the operation.
88       */
89      public InputStream getInputStream(final boolean longOutput, final String user) throws IOException {
90          return getInputStream(longOutput, user, null);
91      }
92  
93      /**
94       * Fingers a user and returns the input stream from the network connection of the finger query. You must first connect to a finger server before calling
95       * this method, and you should disconnect after finishing reading the stream.
96       *
97       * @param longOutput Set to true if long output is requested, false if not.
98       * @param user   The name of the user to finger.
99       * @param encoding   the character encoding that should be used for the query, null for the platform's default encoding
100      * @return The InputStream of the network connection of the finger query. Can be read to obtain finger results.
101      * @throws IOException If an I/O error during the operation.
102      */
103     public InputStream getInputStream(final boolean longOutput, final String user, final String encoding) throws IOException {
104         final DataOutputStream output;
105         final StringBuilder buffer = new StringBuilder(64);
106         if (longOutput) {
107             buffer.append(LONG_FLAG);
108         }
109         buffer.append(user);
110         buffer.append(SocketClient.NETASCII_EOL);
111 
112         // Note: Charsets.toCharset() returns the platform default for null input
113         final byte[] encodedQuery = buffer.toString().getBytes(Charsets.toCharset(encoding).name()); // Java 1.6 can use
114                                                                                                      // charset directly
115 
116         output = new DataOutputStream(new BufferedOutputStream(checkOpenOutputStream(), 1024));
117         output.write(encodedQuery, 0, encodedQuery.length);
118         output.flush();
119 
120         return _input_;
121     }
122 
123     /**
124      * Fingers the connected host and returns the output as a String. You must first connect to a finger server before calling this method, and you should
125      * disconnect afterward. This is equivalent to calling <code>query(longOutput, "")</code>.
126      *
127      * @param longOutput Set to true if long output is requested, false if not.
128      * @return The result of the finger query.
129      * @throws IOException If an I/O error occurs while reading the socket.
130      */
131     public String query(final boolean longOutput) throws IOException {
132         return query(longOutput, "");
133     }
134 
135     /**
136      * Fingers a user at the connected host and returns the output as a String. You must first connect to a finger server before calling this method, and you
137      * should disconnect afterward.
138      *
139      * @param longOutput Set to true if long output is requested, false if not.
140      * @param user   The name of the user to finger.
141      * @return The result of the finger query.
142      * @throws IOException If an I/O error occurs while reading the socket.
143      */
144     public String query(final boolean longOutput, final String user) throws IOException {
145         int read;
146         final StringBuilder result = new StringBuilder(buffer.length);
147 
148         try (final BufferedReader input = new BufferedReader(new InputStreamReader(getInputStream(longOutput, user), getCharset()))) {
149             while (true) {
150                 read = input.read(buffer, 0, buffer.length);
151                 if (read <= 0) {
152                     break;
153                 }
154                 result.append(buffer, 0, read);
155             }
156         }
157 
158         return result.toString();
159     }
160 
161 }