001/* 002 * Licensed to the Apache Software Foundation (ASF) under one or more 003 * contributor license agreements. See the NOTICE file distributed with 004 * this work for additional information regarding copyright ownership. 005 * The ASF licenses this file to You under the Apache License, Version 2.0 006 * (the "License"); you may not use this file except in compliance with 007 * the License. You may obtain a copy of the License at 008 * 009 * https://www.apache.org/licenses/LICENSE-2.0 010 * 011 * Unless required by applicable law or agreed to in writing, software 012 * distributed under the License is distributed on an "AS IS" BASIS, 013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 014 * See the License for the specific language governing permissions and 015 * limitations under the License. 016 */ 017package org.apache.commons.net.finger; 018 019import java.io.BufferedOutputStream; 020import java.io.DataOutputStream; 021import java.io.IOException; 022import java.io.InputStream; 023 024import org.apache.commons.io.Charsets; 025import org.apache.commons.io.IOUtils; 026import org.apache.commons.net.SocketClient; 027 028/** 029 * 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, 030 * 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 031 * host at that port. Here's a sample use: 032 * 033 * <pre> 034 * FingerClient finger; 035 * finger = new FingerClient(); 036 * try { 037 * finger.connect("foo.bar.com"); 038 * System.out.println(finger.query("foobar", false)); 039 * finger.disconnect(); 040 * } catch (IOException e) { 041 * System.err.println("Error I/O exception: " + e.getMessage()); 042 * return; 043 * } 044 * </pre> 045 */ 046public class FingerClient extends SocketClient { 047 048 /** 049 * The default FINGER port. Set to {@value} according to RFC 1288. 050 */ 051 public static final int DEFAULT_PORT = 79; 052 053 private static final String LONG_FLAG = "/W "; 054 055 /** 056 * The default FingerClient constructor. Initializes the default port to {@code DEFAULT_PORT}. 057 */ 058 public FingerClient() { 059 setDefaultPort(DEFAULT_PORT); 060 } 061 062 /** 063 * Fingers the connected host and returns the input stream from the network connection of the finger query. This is equivalent to calling 064 * getInputStream(longOutput, ""). You must first connect to a finger server before calling this method, and you should disconnect after finishing reading 065 * the stream. 066 * 067 * @param longOutput Set to true if long output is requested, false if not. 068 * @return The InputStream of the network connection of the finger query. Can be read to obtain finger results. 069 * @throws IOException If an I/O error during the operation. 070 */ 071 public InputStream getInputStream(final boolean longOutput) throws IOException { 072 return getInputStream(longOutput, ""); 073 } 074 075 /** 076 * 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 077 * this method, and you should disconnect after finishing reading the stream. 078 * 079 * @param longOutput Set to true if long output is requested, false if not. 080 * @param user The name of the user to finger. 081 * @return The InputStream of the network connection of the finger query. Can be read to obtain finger results. 082 * @throws IOException If an I/O error during the operation. 083 */ 084 public InputStream getInputStream(final boolean longOutput, final String user) throws IOException { 085 return getInputStream(longOutput, user, null); 086 } 087 088 /** 089 * 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 090 * this method, and you should disconnect after finishing reading the stream. 091 * 092 * @param longOutput Set to true if long output is requested, false if not. 093 * @param user The name of the user to finger. 094 * @param encoding the character encoding that should be used for the query, null for the platform's default encoding 095 * @return The InputStream of the network connection of the finger query. Can be read to obtain finger results. 096 * @throws IOException If an I/O error during the operation. 097 */ 098 public InputStream getInputStream(final boolean longOutput, final String user, final String encoding) throws IOException { 099 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}