Print this page
Split |
Close |
Expand all |
Collapse all |
--- old/src/share/classes/sun/net/NetworkClient.java
+++ new/src/share/classes/sun/net/NetworkClient.java
1 1 /*
2 2 * Copyright (c) 1994, 2008, Oracle and/or its affiliates. All rights reserved.
3 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 4 *
5 5 * This code is free software; you can redistribute it and/or modify it
6 6 * under the terms of the GNU General Public License version 2 only, as
7 7 * published by the Free Software Foundation. Oracle designates this
8 8 * particular file as subject to the "Classpath" exception as provided
9 9 * by Oracle in the LICENSE file that accompanied this code.
10 10 *
11 11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 14 * version 2 for more details (a copy is included in the LICENSE file that
15 15 * accompanied this code).
16 16 *
17 17 * You should have received a copy of the GNU General Public License version
18 18 * 2 along with this work; if not, write to the Free Software Foundation,
19 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 20 *
21 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 22 * or visit www.oracle.com if you need additional information or have any
23 23 * questions.
24 24 */
25 25 package sun.net;
26 26
27 27 import java.io.*;
28 28 import java.net.Socket;
29 29 import java.net.InetAddress;
30 30 import java.net.InetSocketAddress;
31 31 import java.net.UnknownHostException;
32 32 import java.net.Proxy;
↓ open down ↓ |
32 lines elided |
↑ open up ↑ |
33 33 import java.util.Arrays;
34 34 import java.security.AccessController;
35 35 import java.security.PrivilegedAction;
36 36
37 37 /**
38 38 * This is the base class for network clients.
39 39 *
40 40 * @author Jonathan Payne
41 41 */
42 42 public class NetworkClient {
43 + /* Default value of read timeout, if not specified (infinity) */
44 + public static final int DEFAULT_READ_TIMEOUT = -1;
45 +
46 + /* Default value of connect timeout, if not specified (infinity) */
47 + public static final int DEFAULT_CONNECT_TIMEOUT = -1;
48 +
43 49 protected Proxy proxy = Proxy.NO_PROXY;
44 50 /** Socket for communicating with server. */
45 51 protected Socket serverSocket = null;
46 52
47 53 /** Stream for printing to the server. */
48 54 public PrintStream serverOutput;
49 55
50 56 /** Buffered stream for reading replies from server. */
51 57 public InputStream serverInput;
52 58
53 59 protected static int defaultSoTimeout;
54 60 protected static int defaultConnectTimeout;
55 61
56 - protected int readTimeout = -1;
57 - protected int connectTimeout = -1;
62 + protected int readTimeout = DEFAULT_READ_TIMEOUT;
63 + protected int connectTimeout = DEFAULT_CONNECT_TIMEOUT;
58 64 /* Name of encoding to use for output */
59 65 protected static String encoding;
60 66
61 67 static {
62 68 final int vals[] = {0, 0};
63 69 final String encs[] = { null };
64 70
65 71 AccessController.doPrivileged(
66 72 new PrivilegedAction<Void>() {
67 73 public Void run() {
68 74 vals[0] = Integer.getInteger("sun.net.client.defaultReadTimeout", 0).intValue();
69 75 vals[1] = Integer.getInteger("sun.net.client.defaultConnectTimeout", 0).intValue();
70 76 encs[0] = System.getProperty("file.encoding", "ISO8859_1");
71 77 return null;
72 78 }
73 79 });
74 - if (vals[0] == 0)
75 - defaultSoTimeout = -1;
76 - else
80 + if (vals[0] != 0) {
77 81 defaultSoTimeout = vals[0];
78 -
79 - if (vals[1] == 0)
80 - defaultConnectTimeout = -1;
81 - else
82 + }
83 + if (vals[1] != 0) {
82 84 defaultConnectTimeout = vals[1];
85 + }
83 86
84 -
85 87 encoding = encs[0];
86 88 try {
87 89 if (!isASCIISuperset (encoding)) {
88 90 encoding = "ISO8859_1";
89 91 }
90 92 } catch (Exception e) {
91 93 encoding = "ISO8859_1";
92 94 }
93 95 }
94 96
95 97
96 98 /**
97 99 * Test the named character encoding to verify that it converts ASCII
98 100 * characters correctly. We have to use an ASCII based encoding, or else
99 101 * the NetworkClients will not work correctly in EBCDIC based systems.
100 102 * However, we cannot just use ASCII or ISO8859_1 universally, because in
101 103 * Asian locales, non-ASCII characters may be embedded in otherwise
102 104 * ASCII based protocols (eg. HTTP). The specifications (RFC2616, 2398)
103 105 * are a little ambiguous in this matter. For instance, RFC2398 [part 2.1]
104 106 * says that the HTTP request URI should be escaped using a defined
105 107 * mechanism, but there is no way to specify in the escaped string what
106 108 * the original character set is. It is not correct to assume that
107 109 * UTF-8 is always used (as in URLs in HTML 4.0). For this reason,
108 110 * until the specifications are updated to deal with this issue more
109 111 * comprehensively, and more importantly, HTTP servers are known to
110 112 * support these mechanisms, we will maintain the current behavior
111 113 * where it is possible to send non-ASCII characters in their original
112 114 * unescaped form.
113 115 */
114 116 private static boolean isASCIISuperset (String encoding) throws Exception {
115 117 String chkS = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"+
116 118 "abcdefghijklmnopqrstuvwxyz-_.!~*'();/?:@&=+$,";
117 119
118 120 // Expected byte sequence for string above
119 121 byte[] chkB = { 48,49,50,51,52,53,54,55,56,57,65,66,67,68,69,70,71,72,
120 122 73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,97,98,99,
121 123 100,101,102,103,104,105,106,107,108,109,110,111,112,113,114,
122 124 115,116,117,118,119,120,121,122,45,95,46,33,126,42,39,40,41,59,
123 125 47,63,58,64,38,61,43,36,44};
124 126
125 127 byte[] b = chkS.getBytes (encoding);
126 128 return Arrays.equals (b, chkB);
127 129 }
128 130
129 131 /** Open a connection to the server. */
130 132 public void openServer(String server, int port)
131 133 throws IOException, UnknownHostException {
132 134 if (serverSocket != null)
133 135 closeServer();
134 136 serverSocket = doConnect (server, port);
135 137 try {
136 138 serverOutput = new PrintStream(new BufferedOutputStream(
137 139 serverSocket.getOutputStream()),
138 140 true, encoding);
139 141 } catch (UnsupportedEncodingException e) {
140 142 throw new InternalError(encoding +"encoding not found");
141 143 }
142 144 serverInput = new BufferedInputStream(serverSocket.getInputStream());
143 145 }
144 146
145 147 /**
146 148 * Return a socket connected to the server, with any
147 149 * appropriate options pre-established
148 150 */
149 151 protected Socket doConnect (String server, int port)
150 152 throws IOException, UnknownHostException {
151 153 Socket s;
152 154 if (proxy != null) {
153 155 if (proxy.type() == Proxy.Type.SOCKS) {
154 156 s = AccessController.doPrivileged(
155 157 new PrivilegedAction<Socket>() {
156 158 public Socket run() {
157 159 return new Socket(proxy);
158 160 }});
159 161 } else if (proxy.type() == Proxy.Type.DIRECT) {
160 162 s = createSocket();
161 163 } else {
162 164 // Still connecting through a proxy
163 165 // server & port will be the proxy address and port
164 166 s = new Socket(Proxy.NO_PROXY);
165 167 }
166 168 } else
167 169 s = createSocket();
168 170 // Instance specific timeouts do have priority, that means
169 171 // connectTimeout & readTimeout (-1 means not set)
170 172 // Then global default timeouts
171 173 // Then no timeout.
172 174 if (connectTimeout >= 0) {
173 175 s.connect(new InetSocketAddress(server, port), connectTimeout);
174 176 } else {
175 177 if (defaultConnectTimeout > 0) {
176 178 s.connect(new InetSocketAddress(server, port), defaultConnectTimeout);
177 179 } else {
178 180 s.connect(new InetSocketAddress(server, port));
179 181 }
180 182 }
181 183 if (readTimeout >= 0)
182 184 s.setSoTimeout(readTimeout);
183 185 else if (defaultSoTimeout > 0) {
184 186 s.setSoTimeout(defaultSoTimeout);
185 187 }
186 188 return s;
187 189 }
188 190
189 191 /**
190 192 * The following method, createSocket, is provided to allow the
191 193 * https client to override it so that it may use its socket factory
192 194 * to create the socket.
193 195 */
194 196 protected Socket createSocket() throws IOException {
195 197 return new java.net.Socket();
196 198 }
197 199
198 200 protected InetAddress getLocalAddress() throws IOException {
199 201 if (serverSocket == null)
200 202 throw new IOException("not connected");
201 203 return serverSocket.getLocalAddress();
202 204 }
203 205
204 206 /** Close an open connection to the server. */
205 207 public void closeServer() throws IOException {
206 208 if (! serverIsOpen()) {
207 209 return;
208 210 }
209 211 serverSocket.close();
210 212 serverSocket = null;
211 213 serverInput = null;
212 214 serverOutput = null;
213 215 }
214 216
215 217 /** Return server connection status */
216 218 public boolean serverIsOpen() {
217 219 return serverSocket != null;
218 220 }
219 221
220 222 /** Create connection with host <i>host</i> on port <i>port</i> */
221 223 public NetworkClient(String host, int port) throws IOException {
222 224 openServer(host, port);
223 225 }
224 226
↓ open down ↓ |
130 lines elided |
↑ open up ↑ |
225 227 public NetworkClient() {}
226 228
227 229 public void setConnectTimeout(int timeout) {
228 230 connectTimeout = timeout;
229 231 }
230 232
231 233 public int getConnectTimeout() {
232 234 return connectTimeout;
233 235 }
234 236
237 + /**
238 + * Sets the read timeout.
239 + *
240 + * Note: Public URLConnection (and protocol specific implementations)
241 + * protect against negative timeout values being set. This implemenation,
242 + * and protocol specific implementations, use -1 to represent the default
243 + * read timeout.
244 + *
245 + * This method may be invoked with the default timeout value when the
246 + * protocol handler is trying to reset the timeout after doing a
247 + * potentially blocking internal operation, e.g. cleaning up unread
248 + * response data, buffering error stream response data, etc
249 + */
235 250 public void setReadTimeout(int timeout) {
251 + if (timeout == DEFAULT_READ_TIMEOUT)
252 + timeout = defaultSoTimeout;
253 +
236 254 if (serverSocket != null && timeout >= 0) {
237 255 try {
238 256 serverSocket.setSoTimeout(timeout);
239 257 } catch(IOException e) {
240 258 // We tried...
241 259 }
242 260 }
243 261 readTimeout = timeout;
244 262 }
245 263
246 264 public int getReadTimeout() {
247 265 return readTimeout;
248 266 }
249 267 }
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX