FingerClient.java

  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. import java.io.BufferedOutputStream;
  19. import java.io.BufferedReader;
  20. import java.io.DataOutputStream;
  21. import java.io.IOException;
  22. import java.io.InputStream;
  23. import java.io.InputStreamReader;

  24. import org.apache.commons.net.SocketClient;
  25. import org.apache.commons.net.util.Charsets;

  26. /**
  27.  * 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,
  28.  * 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
  29.  * host at that port. Here's a sample use:
  30.  *
  31.  * <pre>
  32.  * FingerClient finger;
  33.  *
  34.  * finger = new FingerClient();
  35.  *
  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.      * The default FINGER port. Set to 79 according to RFC 1288.
  49.      */
  50.     public static final int DEFAULT_PORT = 79;

  51.     private static final String LONG_FLAG = "/W ";

  52.     private final transient char[] buffer = new char[1024];

  53.     /**
  54.      * The default FingerClient constructor. Initializes the default port to <code>DEFAULT_PORT</code>.
  55.      */
  56.     public FingerClient() {
  57.         setDefaultPort(DEFAULT_PORT);
  58.     }

  59.     /**
  60.      * Fingers the connected host and returns the input stream from the network connection of the finger query. This is equivalent to calling
  61.      * getInputStream(longOutput, ""). You must first connect to a finger server before calling this method, and you should disconnect after finishing reading
  62.      * the stream.
  63.      *
  64.      * @param longOutput Set to true if long output is requested, false if not.
  65.      * @return The InputStream of the network connection of the finger query. Can be read to obtain finger results.
  66.      * @throws IOException If an I/O error during the operation.
  67.      */
  68.     public InputStream getInputStream(final boolean longOutput) throws IOException {
  69.         return getInputStream(longOutput, "");
  70.     }

  71.     /**
  72.      * 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
  73.      * this method, and you should disconnect after finishing reading the stream.
  74.      *
  75.      * @param longOutput Set to true if long output is requested, false if not.
  76.      * @param user   The name of the user to finger.
  77.      * @return The InputStream of the network connection of the finger query. Can be read to obtain finger results.
  78.      * @throws IOException If an I/O error during the operation.
  79.      */
  80.     public InputStream getInputStream(final boolean longOutput, final String user) throws IOException {
  81.         return getInputStream(longOutput, user, null);
  82.     }

  83.     /**
  84.      * 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
  85.      * this method, and you should disconnect after finishing reading the stream.
  86.      *
  87.      * @param longOutput Set to true if long output is requested, false if not.
  88.      * @param user   The name of the user to finger.
  89.      * @param encoding   the character encoding that should be used for the query, null for the platform's default encoding
  90.      * @return The InputStream of the network connection of the finger query. Can be read to obtain finger results.
  91.      * @throws IOException If an I/O error during the operation.
  92.      */
  93.     public InputStream getInputStream(final boolean longOutput, final String user, final String encoding) throws IOException {
  94.         final DataOutputStream output;
  95.         final StringBuilder buffer = new StringBuilder(64);
  96.         if (longOutput) {
  97.             buffer.append(LONG_FLAG);
  98.         }
  99.         buffer.append(user);
  100.         buffer.append(SocketClient.NETASCII_EOL);

  101.         // Note: Charsets.toCharset() returns the platform default for null input
  102.         final byte[] encodedQuery = buffer.toString().getBytes(Charsets.toCharset(encoding).name()); // Java 1.6 can use
  103.                                                                                                      // charset directly

  104.         output = new DataOutputStream(new BufferedOutputStream(checkOpenOutputStream(), 1024));
  105.         output.write(encodedQuery, 0, encodedQuery.length);
  106.         output.flush();

  107.         return _input_;
  108.     }

  109.     /**
  110.      * 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
  111.      * disconnect afterward. This is equivalent to calling <code>query(longOutput, "")</code>.
  112.      *
  113.      * @param longOutput Set to true if long output is requested, false if not.
  114.      * @return The result of the finger query.
  115.      * @throws IOException If an I/O error occurs while reading the socket.
  116.      */
  117.     public String query(final boolean longOutput) throws IOException {
  118.         return query(longOutput, "");
  119.     }

  120.     /**
  121.      * 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
  122.      * should disconnect afterward.
  123.      *
  124.      * @param longOutput Set to true if long output is requested, false if not.
  125.      * @param user   The name of the user to finger.
  126.      * @return The result of the finger query.
  127.      * @throws IOException If an I/O error occurs while reading the socket.
  128.      */
  129.     public String query(final boolean longOutput, final String user) throws IOException {
  130.         int read;
  131.         final StringBuilder result = new StringBuilder(buffer.length);

  132.         try (final BufferedReader input = new BufferedReader(new InputStreamReader(getInputStream(longOutput, user), getCharset()))) {
  133.             while (true) {
  134.                 read = input.read(buffer, 0, buffer.length);
  135.                 if (read <= 0) {
  136.                     break;
  137.                 }
  138.                 result.append(buffer, 0, read);
  139.             }
  140.         }

  141.         return result.toString();
  142.     }

  143. }