View Javadoc
1   /*
2    * Licensed under the GPL License. You may not use this file except in compliance with the License.
3    * You may obtain a copy of the License at
4    *
5    *   https://www.gnu.org/licenses/old-licenses/gpl-2.0.html
6    *
7    * THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING,
8    * WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
9    * PURPOSE.
10   */
11  package psiprobe.tools;
12  
13  import java.io.BufferedReader;
14  import java.io.IOException;
15  import java.io.InputStreamReader;
16  import java.io.PrintStream;
17  import java.net.Socket;
18  import java.nio.charset.StandardCharsets;
19  import java.util.Map;
20  import java.util.TreeMap;
21  
22  import org.slf4j.Logger;
23  import org.slf4j.LoggerFactory;
24  
25  import psiprobe.tools.url.UrlParser;
26  
27  /**
28   * The Class Whois.
29   */
30  public final class Whois {
31  
32    /** The Constant logger. */
33    private static final Logger logger = LoggerFactory.getLogger(Whois.class);
34  
35    /**
36     * Prevent Instantiation.
37     */
38    private Whois() {
39      // Prevent Instantiation
40    }
41  
42    /**
43     * Lookup.
44     *
45     * @param server the server
46     * @param port the port
47     * @param query the query
48     *
49     * @return the response
50     *
51     * @throws IOException Signals that an I/O exception has occurred.
52     */
53    public static Response lookup(String server, int port, String query) throws IOException {
54      return lookup(server, port, query, 5);
55    }
56  
57    /**
58     * Lookup.
59     *
60     * @param server the server
61     * @param port the port
62     * @param query the query
63     * @param timeout the timeout
64     *
65     * @return the response
66     *
67     * @throws IOException Signals that an I/O exception has occurred.
68     */
69    public static Response lookup(String server, int port, String query, long timeout)
70        throws IOException {
71  
72      return lookup(server, port, query, timeout, System.lineSeparator());
73    }
74  
75    /**
76     * Lookup.
77     *
78     * @param server the server
79     * @param port the port
80     * @param query the query
81     * @param timeout the timeout
82     * @param lineSeparator the line separator
83     *
84     * @return the response
85     *
86     * @throws IOException Signals that an I/O exception has occurred.
87     */
88    public static Response lookup(String server, int port, String query, long timeout,
89        String lineSeparator) throws IOException {
90  
91      if (query == null) {
92        return null;
93      }
94  
95      Response response = new Response();
96  
97      response.server = server;
98      response.port = port;
99  
100     try (Socket connection = AsyncSocketFactory.createSocket(server, port, timeout);
101         PrintStream out =
102             new PrintStream(connection.getOutputStream(), true, StandardCharsets.UTF_8.name());
103         BufferedReader in = new BufferedReader(
104             new InputStreamReader(connection.getInputStream(), StandardCharsets.UTF_8))) {
105       out.println(query);
106       StringBuilder sb = new StringBuilder();
107 
108       String line;
109       while ((line = in.readLine()) != null) {
110         sb.append(line).append(lineSeparator);
111         line = line.trim();
112         if (!line.startsWith("%") && !line.startsWith("#")) {
113           int fs = line.indexOf(':');
114           if (fs > 0) {
115             String name = line.substring(0, fs);
116             String value = line.substring(fs + 1).trim();
117             response.data.put(name, value);
118           }
119         }
120       }
121       response.summary = sb.toString();
122 
123       Response newResponse = null;
124       String referral = response.getData().get("ReferralServer");
125 
126       if (referral != null) {
127         try {
128           UrlParser url = new UrlParser(referral);
129           if ("whois".equals(url.getProtocol())) {
130             newResponse = lookup(url.getHost(), url.getPort() == -1 ? 43 : url.getPort(), query,
131                 timeout, lineSeparator);
132           }
133         } catch (IOException e) {
134           logger.trace("Could not contact '{}'", referral, e);
135         }
136       }
137       if (newResponse != null) {
138         response = newResponse;
139       }
140     }
141 
142     return response;
143   }
144 
145   /**
146    * The Class Response.
147    */
148   public static final class Response {
149 
150     /** The summary. */
151     String summary;
152 
153     /** The data. */
154     Map<String, String> data = new TreeMap<>();
155 
156     /** The server. */
157     String server;
158 
159     /** The port. */
160     int port;
161 
162     /**
163      * Gets the summary.
164      *
165      * @return the summary
166      */
167     public String getSummary() {
168       return summary;
169     }
170 
171     /**
172      * Gets the data.
173      *
174      * @return the data
175      */
176     public Map<String, String> getData() {
177       return data;
178     }
179 
180     /**
181      * Gets the server.
182      *
183      * @return the server
184      */
185     public String getServer() {
186       return server;
187     }
188 
189     /**
190      * Gets the port.
191      *
192      * @return the port
193      */
194     public int getPort() {
195       return port;
196     }
197 
198     /**
199      * Instantiates a new response.
200      */
201     private Response() {}
202 
203   }
204 
205 }