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 import java.util.Hashtable;
30
31 /**
32 * CGIClientException is thrown when an error is detected
33 * in a client's request.
34 */
35 class CGIClientException extends Exception {
36
37 public CGIClientException(String s) {
38 super(s);
39 }
40 }
41
42 /**
43 * CGIServerException is thrown when an error occurs here on the server.
44 */
45 class CGIServerException extends Exception {
46
47 public CGIServerException(String s) {
48 super(s);
49 }
50 }
51
52 /**
53 * CGICommandHandler is the interface to an object that handles a
54 * particular supported command.
55 */
56 interface CGICommandHandler {
57
58 /**
59 * Return the string form of the command
60 * to be recognized in the query string.
61 */
62 public String getName();
63
64 /**
65 * Execute the command with the given string as parameter.
66 */
94 ContentLength =
95 Integer.getInteger("CONTENT_LENGTH", 0).intValue();
96 QueryString = System.getProperty("QUERY_STRING", "");
97 RequestMethod = System.getProperty("REQUEST_METHOD", "");
98 ServerName = System.getProperty("SERVER_NAME", "");
99 ServerPort = Integer.getInteger("SERVER_PORT", 0).intValue();
100 return null;
101 }
102 });
103 }
104
105 /* list of handlers for supported commands */
106 private static CGICommandHandler commands[] = {
107 new CGIForwardCommand(),
108 new CGIGethostnameCommand(),
109 new CGIPingCommand(),
110 new CGITryHostnameCommand()
111 };
112
113 /* construct table mapping command strings to handlers */
114 private static Hashtable commandLookup;
115 static {
116 commandLookup = new Hashtable();
117 for (int i = 0; i < commands.length; ++ i)
118 commandLookup.put(commands[i].getName(), commands[i]);
119 }
120
121 /* prevent instantiation of this class */
122 private CGIHandler() {}
123
124 /**
125 * Execute command given in query string on URL. The string before
126 * the first '=' is interpreted as the command name, and the string
127 * after the first '=' is the parameters to the command.
128 */
129 public static void main(String args[])
130 {
131 try {
132 String command, param;
133 int delim = QueryString.indexOf("=");
134 if (delim == -1) {
135 command = QueryString;
136 param = "";
137 }
138 else {
139 command = QueryString.substring(0, delim);
140 param = QueryString.substring(delim + 1);
141 }
142 CGICommandHandler handler =
143 (CGICommandHandler) commandLookup.get(command);
144 if (handler != null)
145 try {
146 handler.execute(param);
147 } catch (CGIClientException e) {
148 returnClientError(e.getMessage());
149 } catch (CGIServerException e) {
150 returnServerError(e.getMessage());
151 }
152 else
153 returnClientError("invalid command: " + command);
154 } catch (Exception e) {
155 returnServerError("internal error: " + e.getMessage());
156 }
157 System.exit(0);
158 }
159
160 /**
161 * Return an HTML error message indicating there was error in
162 * the client's request.
163 */
183 */
184 private static void returnServerError(String message)
185 {
186 System.out.println("Status: 500 Server Error: " + message);
187 System.out.println("Content-type: text/html");
188 System.out.println("");
189 System.out.println("<HTML>" +
190 "<HEAD><TITLE>Java RMI Server Error" +
191 "</TITLE></HEAD>" +
192 "<BODY>");
193 System.out.println("<H1>Java RMI Server Error</H1>");
194 System.out.println("");
195 System.out.println(message);
196 System.out.println("</BODY></HTML>");
197 System.exit(1);
198 }
199 }
200
201 /**
202 * "forward" command: Forward request body to local port on the server,
203 * and send reponse back to client.
204 */
205 final class CGIForwardCommand implements CGICommandHandler {
206
207 public String getName() {
208 return "forward";
209 }
210
211 public void execute(String param) throws CGIClientException, CGIServerException
212 {
213 if (!CGIHandler.RequestMethod.equals("POST"))
214 throw new CGIClientException("can only forward POST requests");
215
216 int port;
217 try {
218 port = Integer.parseInt(param);
219 } catch (NumberFormatException e) {
220 throw new CGIClientException("invalid port number: " + param);
221 }
222 if (port <= 0 || port > 0xFFFF)
223 throw new CGIClientException("invalid port: " + port);
224 if (port < 1024)
225 throw new CGIClientException("permission denied for port: " +
226 port);
227
228 byte buffer[];
229 Socket socket;
230 try {
259 socketOut.flush();
260 } catch (IOException e) {
261 throw new CGIServerException("error writing to server");
262 }
263
264 /*
265 * read response
266 */
267 DataInputStream socketIn;
268 try {
269 socketIn = new DataInputStream(socket.getInputStream());
270 } catch (IOException e) {
271 throw new CGIServerException("error reading from server");
272 }
273 String key = "Content-length:".toLowerCase();
274 boolean contentLengthFound = false;
275 String line;
276 int responseContentLength = -1;
277 do {
278 try {
279 line = socketIn.readLine();
280 } catch (IOException e) {
281 throw new CGIServerException("error reading from server");
282 }
283 if (line == null)
284 throw new CGIServerException(
285 "unexpected EOF reading server response");
286
287 if (line.toLowerCase().startsWith(key)) {
288 if (contentLengthFound)
289 ; // what would we want to do in this case??
290 responseContentLength =
291 Integer.parseInt(line.substring(key.length()).trim());
292 contentLengthFound = true;
293 }
294 } while ((line.length() != 0) &&
295 (line.charAt(0) != '\r') && (line.charAt(0) != '\n'));
296
297 if (!contentLengthFound || responseContentLength < 0)
298 throw new CGIServerException(
299 "missing or invalid content length in server response");
300 buffer = new byte[responseContentLength];
301 try {
302 socketIn.readFully(buffer);
303 } catch (EOFException e) {
304 throw new CGIServerException(
305 "unexpected EOF reading server response");
306 } catch (IOException e) {
307 throw new CGIServerException("error reading from server");
308 }
309
|
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 import java.util.Hashtable;
30
31 /**
32 * CGIClientException is thrown when an error is detected
33 * in a client's request.
34 */
35 class CGIClientException extends Exception {
36 private static final long serialVersionUID = 8147981687059865216L;
37
38 public CGIClientException(String s) {
39 super(s);
40 }
41 }
42
43 /**
44 * CGIServerException is thrown when an error occurs here on the server.
45 */
46 class CGIServerException extends Exception {
47
48 private static final long serialVersionUID = 6928425456704527017L;
49
50 public CGIServerException(String s) {
51 super(s);
52 }
53 }
54
55 /**
56 * CGICommandHandler is the interface to an object that handles a
57 * particular supported command.
58 */
59 interface CGICommandHandler {
60
61 /**
62 * Return the string form of the command
63 * to be recognized in the query string.
64 */
65 public String getName();
66
67 /**
68 * Execute the command with the given string as parameter.
69 */
97 ContentLength =
98 Integer.getInteger("CONTENT_LENGTH", 0).intValue();
99 QueryString = System.getProperty("QUERY_STRING", "");
100 RequestMethod = System.getProperty("REQUEST_METHOD", "");
101 ServerName = System.getProperty("SERVER_NAME", "");
102 ServerPort = Integer.getInteger("SERVER_PORT", 0).intValue();
103 return null;
104 }
105 });
106 }
107
108 /* list of handlers for supported commands */
109 private static CGICommandHandler commands[] = {
110 new CGIForwardCommand(),
111 new CGIGethostnameCommand(),
112 new CGIPingCommand(),
113 new CGITryHostnameCommand()
114 };
115
116 /* construct table mapping command strings to handlers */
117 private static Hashtable<String, CGICommandHandler> commandLookup;
118 static {
119 commandLookup = new Hashtable<>();
120 for (int i = 0; i < commands.length; ++ i)
121 commandLookup.put(commands[i].getName(), commands[i]);
122 }
123
124 /* prevent instantiation of this class */
125 private CGIHandler() {}
126
127 /**
128 * Execute command given in query string on URL. The string before
129 * the first '=' is interpreted as the command name, and the string
130 * after the first '=' is the parameters to the command.
131 */
132 public static void main(String args[])
133 {
134 try {
135 String command, param;
136 int delim = QueryString.indexOf("=");
137 if (delim == -1) {
138 command = QueryString;
139 param = "";
140 }
141 else {
142 command = QueryString.substring(0, delim);
143 param = QueryString.substring(delim + 1);
144 }
145 CGICommandHandler handler =
146 commandLookup.get(command);
147 if (handler != null)
148 try {
149 handler.execute(param);
150 } catch (CGIClientException e) {
151 returnClientError(e.getMessage());
152 } catch (CGIServerException e) {
153 returnServerError(e.getMessage());
154 }
155 else
156 returnClientError("invalid command: " + command);
157 } catch (Exception e) {
158 returnServerError("internal error: " + e.getMessage());
159 }
160 System.exit(0);
161 }
162
163 /**
164 * Return an HTML error message indicating there was error in
165 * the client's request.
166 */
186 */
187 private static void returnServerError(String message)
188 {
189 System.out.println("Status: 500 Server Error: " + message);
190 System.out.println("Content-type: text/html");
191 System.out.println("");
192 System.out.println("<HTML>" +
193 "<HEAD><TITLE>Java RMI Server Error" +
194 "</TITLE></HEAD>" +
195 "<BODY>");
196 System.out.println("<H1>Java RMI Server Error</H1>");
197 System.out.println("");
198 System.out.println(message);
199 System.out.println("</BODY></HTML>");
200 System.exit(1);
201 }
202 }
203
204 /**
205 * "forward" command: Forward request body to local port on the server,
206 * and send response back to client.
207 */
208 final class CGIForwardCommand implements CGICommandHandler {
209
210 public String getName() {
211 return "forward";
212 }
213
214 @SuppressWarnings("deprecation")
215 private String getLine (DataInputStream socketIn) throws IOException {
216 return socketIn.readLine();
217 }
218
219 public void execute(String param) throws CGIClientException, CGIServerException
220 {
221 if (!CGIHandler.RequestMethod.equals("POST"))
222 throw new CGIClientException("can only forward POST requests");
223
224 int port;
225 try {
226 port = Integer.parseInt(param);
227 } catch (NumberFormatException e) {
228 throw new CGIClientException("invalid port number: " + param);
229 }
230 if (port <= 0 || port > 0xFFFF)
231 throw new CGIClientException("invalid port: " + port);
232 if (port < 1024)
233 throw new CGIClientException("permission denied for port: " +
234 port);
235
236 byte buffer[];
237 Socket socket;
238 try {
267 socketOut.flush();
268 } catch (IOException e) {
269 throw new CGIServerException("error writing to server");
270 }
271
272 /*
273 * read response
274 */
275 DataInputStream socketIn;
276 try {
277 socketIn = new DataInputStream(socket.getInputStream());
278 } catch (IOException e) {
279 throw new CGIServerException("error reading from server");
280 }
281 String key = "Content-length:".toLowerCase();
282 boolean contentLengthFound = false;
283 String line;
284 int responseContentLength = -1;
285 do {
286 try {
287 line = getLine(socketIn);
288 } catch (IOException e) {
289 throw new CGIServerException("error reading from server");
290 }
291 if (line == null)
292 throw new CGIServerException(
293 "unexpected EOF reading server response");
294
295 if (line.toLowerCase().startsWith(key)) {
296 if (contentLengthFound){
297 // what would we want to do in this case??
298 }
299 responseContentLength =
300 Integer.parseInt(line.substring(key.length()).trim());
301 contentLengthFound = true;
302 }
303 } while ((line.length() != 0) &&
304 (line.charAt(0) != '\r') && (line.charAt(0) != '\n'));
305
306 if (!contentLengthFound || responseContentLength < 0)
307 throw new CGIServerException(
308 "missing or invalid content length in server response");
309 buffer = new byte[responseContentLength];
310 try {
311 socketIn.readFully(buffer);
312 } catch (EOFException e) {
313 throw new CGIServerException(
314 "unexpected EOF reading server response");
315 } catch (IOException e) {
316 throw new CGIServerException("error reading from server");
317 }
318
|