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    *      https://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.DataOutputStream;
21  import java.io.IOException;
22  import java.io.InputStream;
23  
24  import org.apache.commons.io.Charsets;
25  import org.apache.commons.io.IOUtils;
26  import org.apache.commons.net.SocketClient;
27  
28  /**
29   * 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,
30   * 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
31   * host at that port. Here's a sample use:
32   *
33   * <pre>
34   * FingerClient finger;
35   * finger = new FingerClient();
36   * try {
37   *     finger.connect("foo.bar.com");
38   *     System.out.println(finger.query("foobar", false));
39   *     finger.disconnect();
40   * } catch (IOException e) {
41   *     System.err.println("Error I/O exception: " + e.getMessage());
42   *     return;
43   * }
44   * </pre>
45   */
46  public class FingerClient extends SocketClient {
47  
48      /**
49       * The default FINGER port. Set to {@value} according to RFC 1288.
50       */
51      public static final int DEFAULT_PORT = 79;
52  
53      private static final String LONG_FLAG = "/W ";
54  
55      /**
56       * The default FingerClient constructor. Initializes the default port to {@code DEFAULT_PORT}.
57       */
58      public FingerClient() {
59          setDefaultPort(DEFAULT_PORT);
60      }
61  
62      /**
63       * Fingers the connected host and returns the input stream from the network connection of the finger query. This is equivalent to calling
64       * getInputStream(longOutput, ""). You must first connect to a finger server before calling this method, and you should disconnect after finishing reading
65       * the stream.
66       *
67       * @param longOutput Set to true if long output is requested, false if not.
68       * @return The InputStream of the network connection of the finger query. Can be read to obtain finger results.
69       * @throws IOException If an I/O error during the operation.
70       */
71      public InputStream getInputStream(final boolean longOutput) throws IOException {
72          return getInputStream(longOutput, "");
73      }
74  
75      /**
76       * 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
77       * this method, and you should disconnect after finishing reading the stream.
78       *
79       * @param longOutput Set to true if long output is requested, false if not.
80       * @param user   The name of the user to finger.
81       * @return The InputStream of the network connection of the finger query. Can be read to obtain finger results.
82       * @throws IOException If an I/O error during the operation.
83       */
84      public InputStream getInputStream(final boolean longOutput, final String user) throws IOException {
85          return getInputStream(longOutput, user, null);
86      }
87  
88      /**
89       * 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
90       * this method, and you should disconnect after finishing reading the stream.
91       *
92       * @param longOutput Set to true if long output is requested, false if not.
93       * @param user   The name of the user to finger.
94       * @param encoding   the character encoding that should be used for the query, null for the platform's default encoding
95       * @return The InputStream of the network connection of the finger query. Can be read to obtain finger results.
96       * @throws IOException If an I/O error during the operation.
97       */
98      public InputStream getInputStream(final boolean longOutput, final String user, final String encoding) throws IOException {
99          final DataOutputStream output;
100         final StringBuilder buffer = new StringBuilder(64);
101         if (longOutput) {
102             buffer.append(LONG_FLAG);
103         }
104         buffer.append(user);
105         buffer.append(NETASCII_EOL);
106 
107         // Note: Charsets.toCharset() returns the platform default for null input
108         final byte[] encodedQuery = buffer.toString().getBytes(Charsets.toCharset(encoding));
109 
110         output = new DataOutputStream(new BufferedOutputStream(checkOpenOutputStream(), 1024));
111         output.write(encodedQuery, 0, encodedQuery.length);
112         output.flush();
113 
114         return _input_;
115     }
116 
117     /**
118      * 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
119      * disconnect afterward. This is equivalent to calling {@code query(longOutput, "")}.
120      *
121      * @param longOutput Set to true if long output is requested, false if not.
122      * @return The result of the finger query.
123      * @throws IOException If an I/O error occurs while reading the socket.
124      */
125     public String query(final boolean longOutput) throws IOException {
126         return query(longOutput, "");
127     }
128 
129     /**
130      * 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
131      * should disconnect afterward.
132      *
133      * @param longOutput Set to true if long output is requested, false if not.
134      * @param user   The name of the user to finger.
135      * @return The result of the finger query.
136      * @throws IOException If an I/O error occurs while reading the socket.
137      */
138     public String query(final boolean longOutput, final String user) throws IOException {
139         return IOUtils.toString(() -> getInputStream(longOutput, user), getCharset());
140     }
141 
142 }