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 }