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+ */
25+package sun.rmi.transport.proxy;
26+
27+import java.io.*;
28+import java.net.*;
29+
30+import 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+ */
50+class 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+}