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 */
25package sun.net.www.protocol.gopher;
26
27import java.io.*;
28import java.util.*;
29import java.net.*;
30import sun.net.www.*;
31import sun.net.NetworkClient;
32import java.net.URL;
33import java.net.URLStreamHandler;
34
35import sun.security.action.GetBooleanAction;
36
37/** Class to maintain the state of a gopher fetch and handle the protocol */
38public 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. */
342class 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}