History

My first initial commit with all of mine experimental changes.

Dmitry Kabak (userdima committed 13 years ago

Commit d37b88d1 parent 3f5b46618352 files · +2598093 −-8690Browse files

Showing the changes to java/pkg/sun/net/www/protocol/gopher/GopherClient.java (1 of 18352 files). Show all

Unified · Split

java/pkg/sun/net/www/protocol/gopher/GopherClient.java+357−0
@@ -0,0 +1,357 @@
1+/*
2+ * Copyright (c) 1996, 2004, Oracle and/or its affiliates. All rights reserved.
3+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4+ *
5+ * This code is free software; you can redistribute it and/or modify it
6+ * under the terms of the GNU General Public License version 2 only, as
7+ * published by the Free Software Foundation. Oracle designates this
8+ * particular file as subject to the "Classpath" exception as provided
9+ * by Oracle in the LICENSE file that accompanied this code.
10+ *
11+ * This code is distributed in the hope that it will be useful, but WITHOUT
12+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14+ * version 2 for more details (a copy is included in the LICENSE file that
15+ * accompanied this code).
16+ *
17+ * You should have received a copy of the GNU General Public License version
18+ * 2 along with this work; if not, write to the Free Software Foundation,
19+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20+ *
21+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22+ * or visit www.oracle.com if you need additional information or have any
23+ * questions.
24+ */
25+package sun.net.www.protocol.gopher;
26+
27+import java.io.*;
28+import java.util.*;
29+import java.net.*;
30+import sun.net.www.*;
31+import sun.net.NetworkClient;
32+import java.net.URL;
33+import java.net.URLStreamHandler;
34+
35+import sun.security.action.GetBooleanAction;
36+
37+/** Class to maintain the state of a gopher fetch and handle the protocol */
38+public class GopherClient extends NetworkClient implements Runnable {
39+
40+ /* The following three data members are left in for binary
41+ * backwards-compatibility. Unfortunately, HotJava sets them directly
42+ * when it wants to change the settings. The new design has us not
43+ * cache these, so this is unnecessary, but eliminating the data members
44+ * would break HJB 1.1 under JDK 1.2.
45+ *
46+ * These data members are not used, and their values are meaningless.
47+ * REMIND: Take them out for JDK 2.0!
48+ */
49+
50+ /**
51+ * @deprecated
52+ */
53+ @Deprecated
54+ public static boolean useGopherProxy;
55+
56+ /**
57+ * @deprecated
58+ */
59+ @Deprecated
60+ public static String gopherProxyHost;
61+
62+ /**
63+ * @deprecated
64+ */
65+ @Deprecated
66+ public static int gopherProxyPort;
67+
68+
69+ static {
70+ useGopherProxy = java.security.AccessController.doPrivileged(
71+ new sun.security.action.GetBooleanAction("gopherProxySet"))
72+ .booleanValue();
73+
74+ gopherProxyHost = java.security.AccessController.doPrivileged(
75+ new sun.security.action.GetPropertyAction("gopherProxyHost"));
76+
77+ gopherProxyPort = java.security.AccessController.doPrivileged(
78+ new sun.security.action.GetIntegerAction("gopherProxyPort", 80))
79+ .intValue();
80+ }
81+
82+ PipedOutputStream os;
83+ URL u;
84+ int gtype;
85+ String gkey;
86+ sun.net.www.URLConnection connection;
87+
88+ GopherClient(sun.net.www.URLConnection connection) {
89+ this.connection = connection;
90+ }
91+
92+ /**
93+ * @return true if gopher connections should go through a proxy, according
94+ * to system properties.
95+ */
96+ public static boolean getUseGopherProxy() {
97+ return java.security.AccessController.doPrivileged(
98+ new GetBooleanAction("gopherProxySet")).booleanValue();
99+ }
100+
101+ /**
102+ * @return the proxy host to use, or null if nothing is set.
103+ */
104+ public static String getGopherProxyHost() {
105+ String host = java.security.AccessController.doPrivileged(
106+ new sun.security.action.GetPropertyAction("gopherProxyHost"));
107+ if ("".equals(host)) {
108+ host = null;
109+ }
110+ return host;
111+ }
112+
113+ /**
114+ * @return the proxy port to use. Will default reasonably.
115+ */
116+ public static int getGopherProxyPort() {
117+ return java.security.AccessController.doPrivileged(
118+ new sun.security.action.GetIntegerAction("gopherProxyPort", 80))
119+ .intValue();
120+ }
121+
122+ /** Given a url, setup to fetch the gopher document it refers to */
123+ InputStream openStream(URL u) throws IOException {
124+ this.u = u;
125+ this.os = os;
126+ int i = 0;
127+ String s = u.getFile();
128+ int limit = s.length();
129+ int c = '1';
130+ while (i < limit && (c = s.charAt(i)) == '/')
131+ i++;
132+ gtype = c == '/' ? '1' : c;
133+ if (i < limit)
134+ i++;
135+ gkey = s.substring(i);
136+
137+ openServer(u.getHost(), u.getPort() <= 0 ? 70 : u.getPort());
138+
139+ MessageHeader msgh = new MessageHeader();
140+
141+ switch (gtype) {
142+ case '0':
143+ case '7':
144+ msgh.add("content-type", "text/plain");
145+ break;
146+ case '1':
147+ msgh.add("content-type", "text/html");
148+ break;
149+ case 'g':
150+ case 'I':
151+ msgh.add("content-type", "image/gif");
152+ break;
153+ default:
154+ msgh.add("content-type", "content/unknown");
155+ break;
156+ }
157+ if (gtype != '7') {
158+ serverOutput.print(decodePercent(gkey) + "\r\n");
159+ serverOutput.flush();
160+ } else if ((i = gkey.indexOf('?')) >= 0) {
161+ serverOutput.print(decodePercent(gkey.substring(0, i) + "\t" +
162+ gkey.substring(i + 1) + "\r\n"));
163+ serverOutput.flush();
164+ msgh.add("content-type", "text/html");
165+ } else {
166+ msgh.add("content-type", "text/html");
167+ }
168+ connection.setProperties(msgh);
169+ if (msgh.findValue("content-type") == "text/html") {
170+ os = new PipedOutputStream();
171+ PipedInputStream ret = new PipedInputStream();
172+ ret.connect(os);
173+ new Thread(this).start();
174+ return ret;
175+ }
176+ return new GopherInputStream(this, serverInput);
177+ }
178+
179+ /** Translate all the instances of %NN into the character they represent */
180+ private String decodePercent(String s) {
181+ if (s == null || s.indexOf('%') < 0)
182+ return s;
183+ int limit = s.length();
184+ char d[] = new char[limit];
185+ int dp = 0;
186+ for (int sp = 0; sp < limit; sp++) {
187+ int c = s.charAt(sp);
188+ if (c == '%' && sp + 2 < limit) {
189+ int s1 = s.charAt(sp + 1);
190+ int s2 = s.charAt(sp + 2);
191+ if ('0' <= s1 && s1 <= '9')
192+ s1 = s1 - '0';
193+ else if ('a' <= s1 && s1 <= 'f')
194+ s1 = s1 - 'a' + 10;
195+ else if ('A' <= s1 && s1 <= 'F')
196+ s1 = s1 - 'A' + 10;
197+ else
198+ s1 = -1;
199+ if ('0' <= s2 && s2 <= '9')
200+ s2 = s2 - '0';
201+ else if ('a' <= s2 && s2 <= 'f')
202+ s2 = s2 - 'a' + 10;
203+ else if ('A' <= s2 && s2 <= 'F')
204+ s2 = s2 - 'A' + 10;
205+ else
206+ s2 = -1;
207+ if (s1 >= 0 && s2 >= 0) {
208+ c = (s1 << 4) | s2;
209+ sp += 2;
210+ }
211+ }
212+ d[dp++] = (char) c;
213+ }
214+ return new String(d, 0, dp);
215+ }
216+
217+ /** Turn special characters into the %NN form */
218+ private String encodePercent(String s) {
219+ if (s == null)
220+ return s;
221+ int limit = s.length();
222+ char d[] = null;
223+ int dp = 0;
224+ for (int sp = 0; sp < limit; sp++) {
225+ int c = s.charAt(sp);
226+ if (c <= ' ' || c == '"' || c == '%') {
227+ if (d == null)
228+ d = s.toCharArray();
229+ if (dp + 3 >= d.length) {
230+ char nd[] = new char[dp + 10];
231+ System.arraycopy(d, 0, nd, 0, dp);
232+ d = nd;
233+ }
234+ d[dp] = '%';
235+ int dig = (c >> 4) & 0xF;
236+ d[dp + 1] = (char) (dig < 10 ? '0' + dig : 'A' - 10 + dig);
237+ dig = c & 0xF;
238+ d[dp + 2] = (char) (dig < 10 ? '0' + dig : 'A' - 10 + dig);
239+ dp += 3;
240+ } else {
241+ if (d != null) {
242+ if (dp >= d.length) {
243+ char nd[] = new char[dp + 10];
244+ System.arraycopy(d, 0, nd, 0, dp);
245+ d = nd;
246+ }
247+ d[dp] = (char) c;
248+ }
249+ dp++;
250+ }
251+ }
252+ return d == null ? s : new String(d, 0, dp);
253+ }
254+
255+ /** This method is run as a seperate thread when an incoming gopher
256+ document requires translation to html */
257+ public void run() {
258+ int qpos = -1;
259+ try {
260+ if (gtype == '7' && (qpos = gkey.indexOf('?')) < 0) {
261+ PrintStream ps = new PrintStream(os, false, encoding);
262+ ps.print("<html><head><title>Searchable Gopher Index</title></head>\n<body><h1>Searchable Gopher Index</h1><isindex>\n</body></html>\n");
263+ } else if (gtype != '1' && gtype != '7') {
264+ byte buf[] = new byte[2048];
265+ try {
266+ int n;
267+ while ((n = serverInput.read(buf)) >= 0)
268+ os.write(buf, 0, n);
269+ } catch(Exception e) {
270+ }
271+ } else {
272+ PrintStream ps = new PrintStream(os, false, encoding);
273+ String title = null;
274+ if (gtype == '7')
275+ title = "Results of searching for \"" + gkey.substring(qpos + 1)
276+ + "\" on " + u.getHost();
277+ else
278+ title = "Gopher directory " + gkey + " from " + u.getHost();
279+ ps.print("<html><head><title>");
280+ ps.print(title);
281+ ps.print("</title></head>\n<body>\n<H1>");
282+ ps.print(title);
283+ ps.print("</h1><dl compact>\n");
284+ DataInputStream ds = new DataInputStream(serverInput);
285+ String s;
286+ while ((s = ds.readLine()) != null) {
287+ int len = s.length();
288+ while (len > 0 && s.charAt(len - 1) <= ' ')
289+ len--;
290+ if (len <= 0)
291+ continue;
292+ int key = s.charAt(0);
293+ int t1 = s.indexOf('\t');
294+ int t2 = t1 > 0 ? s.indexOf('\t', t1 + 1) : -1;
295+ int t3 = t2 > 0 ? s.indexOf('\t', t2 + 1) : -1;
296+ if (t3 < 0) {
297+ // ps.print("<br><i>"+s+"</i>\n");
298+ continue;
299+ }
300+ String port = t3 + 1 < len ? ":" + s.substring(t3 + 1, len) : "";
301+ String host = t2 + 1 < t3 ? s.substring(t2 + 1, t3) : u.getHost();
302+ ps.print("<dt><a href=\"gopher://" + host + port + "/"
303+ + s.substring(0, 1) + encodePercent(s.substring(t1 + 1, t2)) + "\">\n");
304+ ps.print("<img align=middle border=0 width=25 height=32 src=");
305+ switch (key) {
306+ default:
307+ ps.print(System.getProperty("java.net.ftp.imagepath.file"));
308+ break;
309+ case '0':
310+ ps.print(System.getProperty("java.net.ftp.imagepath.text"));
311+ break;
312+ case '1':
313+ ps.print(System.getProperty("java.net.ftp.imagepath.directory"));
314+ break;
315+ case 'g':
316+ ps.print(System.getProperty("java.net.ftp.imagepath.gif"));
317+ break;
318+ }
319+ ps.print(".gif align=middle><dd>\n");
320+ ps.print(s.substring(1, t1) + "</a>\n");
321+ }
322+ ps.print("</dl></body>\n");
323+ ps.close();
324+ }
325+
326+ } catch (UnsupportedEncodingException e) {
327+ throw new InternalError(encoding+ " encoding not found");
328+ } catch (IOException e) {
329+ } finally {
330+ try {
331+ closeServer();
332+ os.close();
333+ } catch (IOException e2) {
334+ }
335+ }
336+ }
337+}
338+
339+/** An input stream that does nothing more than hold on to the NetworkClient
340+ that created it. This is used when only the input stream is needed, and
341+ the network client needs to be closed when the input stream is closed. */
342+class GopherInputStream extends FilterInputStream {
343+ NetworkClient parent;
344+
345+ GopherInputStream(NetworkClient o, InputStream fd) {
346+ super(fd);
347+ parent = o;
348+ }
349+
350+ public void close() {
351+ try {
352+ parent.closeServer();
353+ super.close();
354+ } catch (IOException e) {
355+ }
356+ }
357+}