151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski/* 251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Copyright (c) 1996, 2004, Oracle and/or its affiliates. All rights reserved. 351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * This code is free software; you can redistribute it and/or modify it 651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * under the terms of the GNU General Public License version 2 only, as 751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * published by the Free Software Foundation. Oracle designates this 851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * particular file as subject to the "Classpath" exception as provided 951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * by Oracle in the LICENSE file that accompanied this code. 1051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 1151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * This code is distributed in the hope that it will be useful, but WITHOUT 1251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 1351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 1451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * version 2 for more details (a copy is included in the LICENSE file that 1551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * accompanied this code). 1651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 1751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * You should have received a copy of the GNU General Public License version 1851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 2 along with this work; if not, write to the Free Software Foundation, 1951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 2051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 2151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 2251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * or visit www.oracle.com if you need additional information or have any 2351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * questions. 2451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 2551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebskipackage sun.net.www.protocol.gopher; 2651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 2751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebskiimport java.io.*; 2851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebskiimport java.util.*; 2951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebskiimport java.net.*; 3051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebskiimport sun.net.www.*; 3151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebskiimport sun.net.NetworkClient; 3251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebskiimport java.net.URL; 3351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebskiimport java.net.URLStreamHandler; 3451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 3551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebskiimport sun.security.action.GetBooleanAction; 3651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 3751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski/** Class to maintain the state of a gopher fetch and handle the protocol */ 3851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebskipublic class GopherClient extends NetworkClient implements Runnable { 3951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 4051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /* The following three data members are left in for binary 4151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * backwards-compatibility. Unfortunately, HotJava sets them directly 4251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * when it wants to change the settings. The new design has us not 4351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * cache these, so this is unnecessary, but eliminating the data members 4451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * would break HJB 1.1 under JDK 1.2. 4551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 4651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * These data members are not used, and their values are meaningless. 4751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * REMIND: Take them out for JDK 2.0! 4851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 4951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 5051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 5151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @deprecated 5251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 5351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski @Deprecated 5451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public static boolean useGopherProxy; 5551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 5651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 5751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @deprecated 5851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 5951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski @Deprecated 6051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public static String gopherProxyHost; 6151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 6251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 6351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @deprecated 6451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 6551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski @Deprecated 6651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public static int gopherProxyPort; 6751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 6851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 6951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski static { 7051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski useGopherProxy = java.security.AccessController.doPrivileged( 7151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski new sun.security.action.GetBooleanAction("gopherProxySet")) 7251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski .booleanValue(); 7351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 7451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski gopherProxyHost = java.security.AccessController.doPrivileged( 7551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski new sun.security.action.GetPropertyAction("gopherProxyHost")); 7651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 7751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski gopherProxyPort = java.security.AccessController.doPrivileged( 7851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski new sun.security.action.GetIntegerAction("gopherProxyPort", 80)) 7951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski .intValue(); 8051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 8151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 8251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski PipedOutputStream os; 8351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski URL u; 8451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski int gtype; 8551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski String gkey; 8651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski sun.net.www.URLConnection connection; 8751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 8851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski GopherClient(sun.net.www.URLConnection connection) { 8951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski this.connection = connection; 9051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 9151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 9251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 9351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @return true if gopher connections should go through a proxy, according 9451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * to system properties. 9551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 9651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public static boolean getUseGopherProxy() { 9751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return java.security.AccessController.doPrivileged( 9851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski new GetBooleanAction("gopherProxySet")).booleanValue(); 9951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 10051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 10151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 10251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @return the proxy host to use, or null if nothing is set. 10351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 10451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public static String getGopherProxyHost() { 10551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski String host = java.security.AccessController.doPrivileged( 10651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski new sun.security.action.GetPropertyAction("gopherProxyHost")); 10751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if ("".equals(host)) { 10851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski host = null; 10951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 11051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return host; 11151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 11251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 11351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 11451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @return the proxy port to use. Will default reasonably. 11551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 11651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public static int getGopherProxyPort() { 11751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return java.security.AccessController.doPrivileged( 11851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski new sun.security.action.GetIntegerAction("gopherProxyPort", 80)) 11951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski .intValue(); 12051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 12151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 12251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** Given a url, setup to fetch the gopher document it refers to */ 12351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski InputStream openStream(URL u) throws IOException { 12451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski this.u = u; 12551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski this.os = os; 12651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski int i = 0; 12751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski String s = u.getFile(); 12851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski int limit = s.length(); 12951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski int c = '1'; 13051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski while (i < limit && (c = s.charAt(i)) == '/') 13151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski i++; 13251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski gtype = c == '/' ? '1' : c; 13351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (i < limit) 13451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski i++; 13551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski gkey = s.substring(i); 13651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 13751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski openServer(u.getHost(), u.getPort() <= 0 ? 70 : u.getPort()); 13851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 13951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski MessageHeader msgh = new MessageHeader(); 14051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 14151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski switch (gtype) { 14251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski case '0': 14351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski case '7': 14451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski msgh.add("content-type", "text/plain"); 14551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski break; 14651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski case '1': 14751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski msgh.add("content-type", "text/html"); 14851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski break; 14951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski case 'g': 15051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski case 'I': 15151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski msgh.add("content-type", "image/gif"); 15251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski break; 15351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski default: 15451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski msgh.add("content-type", "content/unknown"); 15551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski break; 15651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 15751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (gtype != '7') { 15851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski serverOutput.print(decodePercent(gkey) + "\r\n"); 15951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski serverOutput.flush(); 16051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } else if ((i = gkey.indexOf('?')) >= 0) { 16151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski serverOutput.print(decodePercent(gkey.substring(0, i) + "\t" + 16251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski gkey.substring(i + 1) + "\r\n")); 16351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski serverOutput.flush(); 16451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski msgh.add("content-type", "text/html"); 16551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } else { 16651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski msgh.add("content-type", "text/html"); 16751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 16851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski connection.setProperties(msgh); 16951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (msgh.findValue("content-type") == "text/html") { 17051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski os = new PipedOutputStream(); 17151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski PipedInputStream ret = new PipedInputStream(); 17251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski ret.connect(os); 17351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski new Thread(this).start(); 17451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return ret; 17551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 17651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return new GopherInputStream(this, serverInput); 17751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 17851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 17951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** Translate all the instances of %NN into the character they represent */ 18051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski private String decodePercent(String s) { 18151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (s == null || s.indexOf('%') < 0) 18251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return s; 18351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski int limit = s.length(); 18451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski char d[] = new char[limit]; 18551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski int dp = 0; 18651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski for (int sp = 0; sp < limit; sp++) { 18751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski int c = s.charAt(sp); 18851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (c == '%' && sp + 2 < limit) { 18951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski int s1 = s.charAt(sp + 1); 19051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski int s2 = s.charAt(sp + 2); 19151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if ('0' <= s1 && s1 <= '9') 19251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski s1 = s1 - '0'; 19351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski else if ('a' <= s1 && s1 <= 'f') 19451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski s1 = s1 - 'a' + 10; 19551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski else if ('A' <= s1 && s1 <= 'F') 19651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski s1 = s1 - 'A' + 10; 19751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski else 19851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski s1 = -1; 19951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if ('0' <= s2 && s2 <= '9') 20051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski s2 = s2 - '0'; 20151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski else if ('a' <= s2 && s2 <= 'f') 20251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski s2 = s2 - 'a' + 10; 20351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski else if ('A' <= s2 && s2 <= 'F') 20451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski s2 = s2 - 'A' + 10; 20551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski else 20651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski s2 = -1; 20751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (s1 >= 0 && s2 >= 0) { 20851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski c = (s1 << 4) | s2; 20951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski sp += 2; 21051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 21151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 21251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski d[dp++] = (char) c; 21351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 21451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return new String(d, 0, dp); 21551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 21651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 21751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** Turn special characters into the %NN form */ 21851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski private String encodePercent(String s) { 21951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (s == null) 22051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return s; 22151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski int limit = s.length(); 22251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski char d[] = null; 22351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski int dp = 0; 22451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski for (int sp = 0; sp < limit; sp++) { 22551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski int c = s.charAt(sp); 22651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (c <= ' ' || c == '"' || c == '%') { 22751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (d == null) 22851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski d = s.toCharArray(); 22951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (dp + 3 >= d.length) { 23051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski char nd[] = new char[dp + 10]; 23151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski System.arraycopy(d, 0, nd, 0, dp); 23251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski d = nd; 23351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 23451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski d[dp] = '%'; 23551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski int dig = (c >> 4) & 0xF; 23651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski d[dp + 1] = (char) (dig < 10 ? '0' + dig : 'A' - 10 + dig); 23751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski dig = c & 0xF; 23851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski d[dp + 2] = (char) (dig < 10 ? '0' + dig : 'A' - 10 + dig); 23951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski dp += 3; 24051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } else { 24151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (d != null) { 24251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (dp >= d.length) { 24351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski char nd[] = new char[dp + 10]; 24451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski System.arraycopy(d, 0, nd, 0, dp); 24551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski d = nd; 24651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 24751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski d[dp] = (char) c; 24851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 24951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski dp++; 25051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 25151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 25251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return d == null ? s : new String(d, 0, dp); 25351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 25451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 25551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** This method is run as a seperate thread when an incoming gopher 25651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski document requires translation to html */ 25751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public void run() { 25851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski int qpos = -1; 25951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski try { 26051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (gtype == '7' && (qpos = gkey.indexOf('?')) < 0) { 26151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski PrintStream ps = new PrintStream(os, false, encoding); 26251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski ps.print("<html><head><title>Searchable Gopher Index</title></head>\n<body><h1>Searchable Gopher Index</h1><isindex>\n</body></html>\n"); 26351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } else if (gtype != '1' && gtype != '7') { 26451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski byte buf[] = new byte[2048]; 26551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski try { 26651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski int n; 26751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski while ((n = serverInput.read(buf)) >= 0) 26851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski os.write(buf, 0, n); 26951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } catch(Exception e) { 27051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 27151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } else { 27251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski PrintStream ps = new PrintStream(os, false, encoding); 27351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski String title = null; 27451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (gtype == '7') 27551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski title = "Results of searching for \"" + gkey.substring(qpos + 1) 27651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski + "\" on " + u.getHost(); 27751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski else 27851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski title = "Gopher directory " + gkey + " from " + u.getHost(); 27951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski ps.print("<html><head><title>"); 28051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski ps.print(title); 28151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski ps.print("</title></head>\n<body>\n<H1>"); 28251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski ps.print(title); 28351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski ps.print("</h1><dl compact>\n"); 28451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski DataInputStream ds = new DataInputStream(serverInput); 28551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski String s; 28651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski while ((s = ds.readLine()) != null) { 28751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski int len = s.length(); 28851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski while (len > 0 && s.charAt(len - 1) <= ' ') 28951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski len--; 29051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (len <= 0) 29151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski continue; 29251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski int key = s.charAt(0); 29351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski int t1 = s.indexOf('\t'); 29451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski int t2 = t1 > 0 ? s.indexOf('\t', t1 + 1) : -1; 29551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski int t3 = t2 > 0 ? s.indexOf('\t', t2 + 1) : -1; 29651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (t3 < 0) { 29751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // ps.print("<br><i>"+s+"</i>\n"); 29851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski continue; 29951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 30051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski String port = t3 + 1 < len ? ":" + s.substring(t3 + 1, len) : ""; 30151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski String host = t2 + 1 < t3 ? s.substring(t2 + 1, t3) : u.getHost(); 30251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski ps.print("<dt><a href=\"gopher://" + host + port + "/" 30351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski + s.substring(0, 1) + encodePercent(s.substring(t1 + 1, t2)) + "\">\n"); 30451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski ps.print("<img align=middle border=0 width=25 height=32 src="); 30551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski switch (key) { 30651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski default: 30751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski ps.print(System.getProperty("java.net.ftp.imagepath.file")); 30851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski break; 30951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski case '0': 31051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski ps.print(System.getProperty("java.net.ftp.imagepath.text")); 31151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski break; 31251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski case '1': 31351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski ps.print(System.getProperty("java.net.ftp.imagepath.directory")); 31451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski break; 31551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski case 'g': 31651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski ps.print(System.getProperty("java.net.ftp.imagepath.gif")); 31751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski break; 31851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 31951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski ps.print(".gif align=middle><dd>\n"); 32051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski ps.print(s.substring(1, t1) + "</a>\n"); 32151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 32251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski ps.print("</dl></body>\n"); 32351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski ps.close(); 32451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 32551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 32651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } catch (UnsupportedEncodingException e) { 32751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throw new InternalError(encoding+ " encoding not found"); 32851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } catch (IOException e) { 32951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } finally { 33051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski try { 33151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski closeServer(); 33251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski os.close(); 33351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } catch (IOException e2) { 33451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 33551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 33651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 33751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski} 33851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 33951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski/** An input stream that does nothing more than hold on to the NetworkClient 34051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski that created it. This is used when only the input stream is needed, and 34151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski the network client needs to be closed when the input stream is closed. */ 34251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebskiclass GopherInputStream extends FilterInputStream { 34351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski NetworkClient parent; 34451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 34551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski GopherInputStream(NetworkClient o, InputStream fd) { 34651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski super(fd); 34751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski parent = o; 34851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 34951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 35051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public void close() { 35151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski try { 35251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski parent.closeServer(); 35351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski super.close(); 35451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } catch (IOException e) { 35551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 35651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 35751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski} 358