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/rmi/transport/proxy/HttpSendSocket.java (1 of 18352 files). Show all

Unified · Split

java/pkg/sun/rmi/transport/proxy/HttpSendSocket.java+343−0
@@ -0,0 +1,343 @@
1/*
2 * Copyright (c) 1996, 2008, 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.rmi.transport.proxy;
26
27import java.io.*;
28import java.net.*;
29
30import sun.rmi.runtime.Log;
31
32/**
33 * The HttpSendSocket class extends the java.net.Socket class
34 * by enclosing the data output stream in, then extracting the input
35 * stream from, an HTTP protocol transmission.
36 *
37 * NOTES:
38 *
39 * Since the length of the output request must be known before the
40 * HTTP header can be completed, all of the output is buffered by
41 * an HttpOutputStream object until either an attempt is made to
42 * read from this socket, or the socket is explicitly closed.
43 *
44 * On the first read attempt to read from this socket, the buffered
45 * output is sent to the destination as the body of an HTTP POST
46 * request. All reads will then acquire data from the body of
47 * the response. A subsequent attempt to write to this socket will
48 * throw an IOException.
49 */
50class HttpSendSocket extends Socket implements RMISocketInfo {
51
52 /** the host to connect to */
53 protected String host;
54
55 /** the port to connect to */
56 protected int port;
57
58 /** the URL to forward through */
59 protected URL url;
60
61 /** the object managing this connection through the URL */
62 protected URLConnection conn = null;
63
64 /** internal input stream for this socket */
65 protected InputStream in = null;
66
67 /** internal output stream for this socket */
68 protected OutputStream out = null;
69
70 /** the notifying input stream returned to users */
71 protected HttpSendInputStream inNotifier;
72
73 /** the notifying output stream returned to users */
74 protected HttpSendOutputStream outNotifier;
75
76 /**
77 * Line separator string. This is the value of the line.separator
78 * property at the moment that the socket was created.
79 */
80 private String lineSeparator =
81 java.security.AccessController.doPrivileged(
82 new sun.security.action.GetPropertyAction("line.separator"));
83
84 /**
85 * Create a stream socket and connect it to the specified port on
86 * the specified host.
87 * @param host the host
88 * @param port the port
89 */
90 public HttpSendSocket(String host, int port, URL url) throws IOException
91 {
92 super((SocketImpl)null); // no underlying SocketImpl for this object
93
94 if (RMIMasterSocketFactory.proxyLog.isLoggable(Log.VERBOSE)) {
95 RMIMasterSocketFactory.proxyLog.log(Log.VERBOSE,
96 "host = " + host + ", port = " + port + ", url = " + url);
97 }
98
99 this.host = host;
100 this.port = port;
101 this.url = url;
102
103 inNotifier = new HttpSendInputStream(null, this);
104 outNotifier = new HttpSendOutputStream(writeNotify(), this);
105 }
106
107 /**
108 * Create a stream socket and connect it to the specified port on
109 * the specified host.
110 * @param host the host
111 * @param port the port
112 */
113 public HttpSendSocket(String host, int port) throws IOException
114 {
115 this(host, port, new URL("http", host, port, "/"));
116 }
117
118 /**
119 * Create a stream socket and connect it to the specified address on
120 * the specified port.
121 * @param address the address
122 * @param port the port
123 */
124 public HttpSendSocket(InetAddress address, int port) throws IOException
125 {
126 this(address.getHostName(), port);
127 }
128
129 /**
130 * Indicate that this socket is not reusable.
131 */
132 public boolean isReusable()
133 {
134 return false;
135 }
136
137 /**
138 * Create a new socket connection to host (or proxy), and prepare to
139 * send HTTP transmission.
140 */
141 public synchronized OutputStream writeNotify() throws IOException
142 {
143 if (conn != null) {
144 throw new IOException("attempt to write on HttpSendSocket after " +
145 "request has been sent");
146 }
147
148 conn = url.openConnection();
149 conn.setDoOutput(true);
150 conn.setUseCaches(false);
151 conn.setRequestProperty("Content-type", "application/octet-stream");
152
153 inNotifier.deactivate();
154 in = null;
155
156 return out = conn.getOutputStream();
157 }
158
159 /**
160 * Send HTTP output transmission and prepare to receive response.
161 */
162 public synchronized InputStream readNotify() throws IOException
163 {
164 RMIMasterSocketFactory.proxyLog.log(Log.VERBOSE,
165 "sending request and activating input stream");
166
167 outNotifier.deactivate();
168 out.close();
169 out = null;
170
171 try {
172 in = conn.getInputStream();
173 } catch (IOException e) {
174 RMIMasterSocketFactory.proxyLog.log(Log.BRIEF,
175 "failed to get input stream, exception: ", e);
176
177 throw new IOException("HTTP request failed");
178 }
179
180 /*
181 * If an HTTP error response is returned, sometimes an IOException
182 * is thrown, which is handled above, and other times it isn't, and
183 * the error response body will be available for reading.
184 * As a safety net to catch any such unexpected HTTP behavior, we
185 * verify that the content type of the response is what the
186 * HttpOutputStream generates: "application/octet-stream".
187 * (Servers' error responses will generally be "text/html".)
188 * Any error response body is printed to the log.
189 */
190 String contentType = conn.getContentType();
191 if (contentType == null ||
192 !conn.getContentType().equals("application/octet-stream"))
193 {
194 if (RMIMasterSocketFactory.proxyLog.isLoggable(Log.BRIEF)) {
195 String message;
196 if (contentType == null) {
197 message = "missing content type in response" +
198 lineSeparator;
199 } else {
200 message = "invalid content type in response: " +
201 contentType + lineSeparator;
202 }
203
204 message += "HttpSendSocket.readNotify: response body: ";
205 try {
206 DataInputStream din = new DataInputStream(in);
207 String line;
208 while ((line = din.readLine()) != null)
209 message += line + lineSeparator;
210 } catch (IOException e) {
211 }
212 RMIMasterSocketFactory.proxyLog.log(Log.BRIEF, message);
213 }
214
215 throw new IOException("HTTP request failed");
216 }
217
218 return in;
219 }
220
221 /**
222 * Get the address to which the socket is connected.
223 */
224 public InetAddress getInetAddress()
225 {
226 try {
227 return InetAddress.getByName(host);
228 } catch (UnknownHostException e) {
229 return null; // null if couldn't resolve destination host
230 }
231 }
232
233 /**
234 * Get the local address to which the socket is bound.
235 */
236 public InetAddress getLocalAddress()
237 {
238 try {
239 return InetAddress.getLocalHost();
240 } catch (UnknownHostException e) {
241 return null; // null if couldn't determine local host
242 }
243 }
244
245 /**
246 * Get the remote port to which the socket is connected.
247 */
248 public int getPort()
249 {
250 return port;
251 }
252
253 /**
254 * Get the local port to which the socket is connected.
255 */
256 public int getLocalPort()
257 {
258 return -1; // request not applicable to this socket type
259 }
260
261 /**
262 * Get an InputStream for this socket.
263 */
264 public InputStream getInputStream() throws IOException
265 {
266 return inNotifier;
267 }
268
269 /**
270 * Get an OutputStream for this socket.
271 */
272 public OutputStream getOutputStream() throws IOException
273 {
274 return outNotifier;
275 }
276
277 /**
278 * Enable/disable TCP_NODELAY.
279 * This operation has no effect for an HttpSendSocket.
280 */
281 public void setTcpNoDelay(boolean on) throws SocketException
282 {
283 }
284
285 /**
286 * Retrieve whether TCP_NODELAY is enabled.
287 */
288 public boolean getTcpNoDelay() throws SocketException
289 {
290 return false; // imply option is disabled
291 }
292
293 /**
294 * Enable/disable SO_LINGER with the specified linger time.
295 * This operation has no effect for an HttpSendSocket.
296 */
297 public void setSoLinger(boolean on, int val) throws SocketException
298 {
299 }
300
301 /**
302 * Retrive setting for SO_LINGER.
303 */
304 public int getSoLinger() throws SocketException
305 {
306 return -1; // imply option is disabled
307 }
308
309 /**
310 * Enable/disable SO_TIMEOUT with the specified timeout
311 * This operation has no effect for an HttpSendSocket.
312 */
313 public synchronized void setSoTimeout(int timeout) throws SocketException
314 {
315 }
316
317 /**
318 * Retrive setting for SO_TIMEOUT.
319 */
320 public synchronized int getSoTimeout() throws SocketException
321 {
322 return 0; // imply option is disabled
323 }
324
325 /**
326 * Close the socket.
327 */
328 public synchronized void close() throws IOException
329 {
330 if (out != null) // push out transmission if not done
331 out.close();
332 }
333
334 /**
335 * Return string representation of this pseudo-socket.
336 */
337 public String toString()
338 {
339 return "HttpSendSocket[host=" + host +
340 ",port=" + port +
341 ",url=" + url + "]";
342 }
343}