Changeset 22675 in osm
- Timestamp:
- 2010-08-17T22:52:49+02:00 (14 years ago)
- Location:
- applications/editors/josm/plugins/remotecontrol
- Files:
-
- 11 added
- 4 edited
Legend:
- Unmodified
- Added
- Removed
-
applications/editors/josm/plugins/remotecontrol/build.xml
r22479 r22675 52 52 <jar destfile="${plugin.jar}" basedir="${plugin.build.dir}"> 53 53 <manifest> 54 <attribute name="Author" value="Frederik Ramm "/>54 <attribute name="Author" value="Frederik Ramm, Bodo Meissner"/> 55 55 <attribute name="Plugin-Class" value="org.openstreetmap.josm.plugins.remotecontrol.RemoteControlPlugin"/> 56 56 <attribute name="Plugin-Date" value="${version.entry.commit.date}"/> … … 60 60 <attribute name="Plugin-Mainversion" value="${plugin.main.version}"/> 61 61 <attribute name="Plugin-Version" value="${version.entry.commit.revision}"/> 62 <!-- This plugin must be loaded before any plugin that may want to register 63 handlers for additional remote commands.--> 64 <attribute name="Plugin-Stage" value="20"/> 62 65 </manifest> 63 66 </jar> -
applications/editors/josm/plugins/remotecontrol/src/org/openstreetmap/josm/plugins/remotecontrol/RemoteControlPlugin.java
r19471 r22675 21 21 { 22 22 super(info); 23 /* 24 System.out.println("constructor " + this.getClass().getName() + " (" + info.name + 25 " v " + info.version + " stage " + info.stage + ")"); 26 */ 23 27 restartServer(); 24 28 } … … 50 54 } 51 55 } 56 57 /** 58 * Add external external request handler. 59 * Can be used by other plug-ins that want to use remote control. 60 * 61 * @param handler The additional request handler. 62 */ 63 public void addRequestHandler(String command, Class<? extends RequestHandler> handlerClass) 64 { 65 RequestProcessor.addRequestHandlerClass(command, handlerClass); 66 } 67 52 68 } -
applications/editors/josm/plugins/remotecontrol/src/org/openstreetmap/josm/plugins/remotecontrol/RemoteControlPreferences.java
r22479 r22675 13 13 14 14 import org.openstreetmap.josm.Main; 15 import org.openstreetmap.josm.gui.preferences.PreferenceDialog;16 15 import org.openstreetmap.josm.gui.preferences.PreferenceSetting; 17 16 import org.openstreetmap.josm.gui.preferences.PreferenceTabbedPane; -
applications/editors/josm/plugins/remotecontrol/src/org/openstreetmap/josm/plugins/remotecontrol/RequestProcessor.java
r22479 r22675 1 1 package org.openstreetmap.josm.plugins.remotecontrol; 2 2 3 import static org.openstreetmap.josm.tools.I18n.tr;4 5 import java.awt.geom.Area;6 import java.awt.geom.Rectangle2D;7 3 import java.io.BufferedInputStream; 8 4 import java.io.BufferedOutputStream; … … 14 10 import java.io.Writer; 15 11 import java.net.Socket; 16 import java.net.URLDecoder;17 12 import java.util.Date; 18 13 import java.util.HashMap; 19 import java.util.HashSet;20 14 import java.util.StringTokenizer; 21 import java.util.concurrent.Future; 22 23 import javax.swing.JOptionPane; 24 25 import org.openstreetmap.josm.Main; 26 import org.openstreetmap.josm.actions.AutoScaleAction; 27 import org.openstreetmap.josm.actions.downloadtasks.DownloadOsmTask; 28 import org.openstreetmap.josm.actions.downloadtasks.DownloadTask; 29 import org.openstreetmap.josm.actions.downloadtasks.PostDownloadHandler; 30 import org.openstreetmap.josm.command.AddCommand; 31 import org.openstreetmap.josm.data.Bounds; 32 import org.openstreetmap.josm.data.coor.LatLon; 33 import org.openstreetmap.josm.data.osm.DataSet; 34 import org.openstreetmap.josm.data.osm.Node; 35 import org.openstreetmap.josm.data.osm.OsmPrimitive; 36 import org.openstreetmap.josm.data.osm.Relation; 37 import org.openstreetmap.josm.data.osm.Way; 38 import org.openstreetmap.josm.data.osm.visitor.BoundingXYVisitor; 15 16 import org.openstreetmap.josm.plugins.remotecontrol.handler.AddNodeHandler; 17 import org.openstreetmap.josm.plugins.remotecontrol.handler.ImportHandler; 18 import org.openstreetmap.josm.plugins.remotecontrol.handler.LoadAndZoomHandler; 19 import org.openstreetmap.josm.plugins.remotecontrol.handler.VersionHandler; 39 20 40 21 /** 41 22 * Processes HTTP "remote control" requests. 42 23 */ 43 public class RequestProcessor extends Thread 44 { 45 /**46 * RemoteControl protocol version.47 * Change minor number for compatible interface extensions. Change major number in case of incompatiblechanges.24 public class RequestProcessor extends Thread { 25 /** 26 * RemoteControl protocol version. Change minor number for compatible 27 * interface extensions. Change major number in case of incompatible 28 * changes. 48 29 */ 49 30 public static final String PROTOCOLVERSION = "{\"protocolversion\": {\"major\": 1, \"minor\": 0}, \"application\": \"JOSM RemoteControl\"}"; 50 31 51 52 /** The socket this processor listens on */ 53 private Socket request; 54 55 private class AlreadyLoadedException extends Exception {}; 56 private class LoadDeniedException extends Exception {}; 57 58 /** 59 * Constructor 60 * 61 * @param request 62 */ 63 public RequestProcessor(Socket request) 64 { 65 super("RemoteControl request processor"); 66 this.setDaemon(true); 67 this.request = request; 68 } 69 70 /** 71 * Spawns a new thread for the request 72 * 73 * @param request The WMS request 74 */ 75 public static void processRequest(Socket request) 76 { 77 RequestProcessor processor = new RequestProcessor(request); 78 processor.start(); 79 } 80 81 /** 82 * The work is done here. 83 */ 84 public void run() 85 { 86 Writer out = null; 87 try 88 { 89 String content = "OK\r\n"; 90 String contentType = "text/plain"; 91 92 OutputStream raw = new BufferedOutputStream( request.getOutputStream()); 93 out = new OutputStreamWriter(raw); 94 Reader in = new InputStreamReader(new BufferedInputStream(request.getInputStream()), "ASCII"); 95 96 StringBuffer requestLine = new StringBuffer(); 97 while (requestLine.length() < 1024) 98 { 99 int c = in.read(); 100 if (c == '\r' || c == '\n') break; 101 requestLine.append((char) c); 102 } 103 104 System.out.println("RemoteControl received: " + requestLine); 105 String get = requestLine.toString(); 106 StringTokenizer st = new StringTokenizer(get); 107 if (!st.hasMoreTokens()) { sendError(out); return; } 108 String method = st.nextToken(); 109 if (!st.hasMoreTokens()) { sendError(out); return; } 110 String url = st.nextToken(); 111 112 if (!method.equals("GET")) { 113 sendNotImplemented(out); 114 return; 115 } 116 117 st = new StringTokenizer(url, "&?"); 118 String command = null; 119 HashMap<String,String> args = new HashMap<String,String>(); 120 while (st.hasMoreTokens()) 121 { 122 String param = st.nextToken(); 123 if (command == null) { 124 command = param; 125 } else { 126 int eq = param.indexOf("="); 127 if (eq>-1) args.put(param.substring(0,eq), param.substring(eq+1)); 128 } 129 } 130 131 if (command.equals("/load_and_zoom")) { 132 if (Main.pref.getBoolean("remotecontrol.always-confirm", false)) { 133 if (JOptionPane.showConfirmDialog(Main.parent, 134 "<html>" + tr("Remote Control has been asked to load data from the API.") + 135 "<br>" + tr("Request details: {0}", url) + "<br>" + tr("Do you want to allow this?"), 136 tr("Confirm Remote Control action"), 137 JOptionPane.YES_NO_OPTION) != JOptionPane.YES_OPTION) { 138 sendForbidden(out); 139 return; 140 } 141 } 142 DownloadTask osmTask = new DownloadOsmTask(); 143 if (!(args.containsKey("bottom") && args.containsKey("top") && 144 args.containsKey("left") && args.containsKey("right"))) { 145 sendBadRequest(out); 146 System.out.println("load_and_zoom remote control request must have bottom,top,left,right parameters"); 147 return; 148 } 149 double minlat = 0; 150 double maxlat = 0; 151 double minlon = 0; 152 double maxlon = 0; 153 try { 154 minlat = Double.parseDouble(args.get("bottom")); 155 maxlat = Double.parseDouble(args.get("top")); 156 minlon = Double.parseDouble(args.get("left")); 157 maxlon = Double.parseDouble(args.get("right")); 158 159 if (!Main.pref.getBoolean("remotecontrol.permission.load-data", true)) 160 throw new LoadDeniedException(); 161 162 // find out whether some data has already been downloaded 163 Area present = null; 164 DataSet ds = Main.main.getCurrentDataSet(); 165 if (ds != null) 166 present = ds.getDataSourceArea(); 167 if (present != null && !present.isEmpty()) { 168 Area toDownload = new Area(new Rectangle2D.Double(minlon,minlat,maxlon-minlon,maxlat-minlat)); 169 toDownload.subtract(present); 170 if (toDownload.isEmpty()) throw new AlreadyLoadedException(); 171 // the result might not be a rectangle (L shaped etc) 172 Rectangle2D downloadBounds = toDownload.getBounds2D(); 173 minlat = downloadBounds.getMinY(); 174 minlon = downloadBounds.getMinX(); 175 maxlat = downloadBounds.getMaxY(); 176 maxlon = downloadBounds.getMaxX(); 177 } 178 Future<?> future = osmTask.download(false /*no new layer*/, new Bounds(minlat,minlon,maxlat,maxlon), null /* let the task manage the progress monitor */); 179 Main.worker.submit(new PostDownloadHandler(osmTask, future)); 180 } catch (AlreadyLoadedException ex) { 181 System.out.println("RemoteControl: no download necessary"); 182 } catch (LoadDeniedException ex) { 183 System.out.println("RemoteControl: download forbidden by preferences"); 184 sendForbidden(out); 185 return; 186 } catch (Exception ex) { 187 sendError(out); 188 System.out.println("RemoteControl: Error parsing load_and_zoom remote control request:"); 189 ex.printStackTrace(); 190 return; 191 } 192 if (args.containsKey("select") && Main.pref.getBoolean("remotecontrol.permission.change-selection", true)) { 193 // select objects after downloading, zoom to selection. 194 final String selection = args.get("select"); 195 Main.worker.execute(new Runnable() { 196 public void run() { 197 HashSet<Long> ways = new HashSet<Long>(); 198 HashSet<Long> nodes = new HashSet<Long>(); 199 HashSet<Long> relations = new HashSet<Long>(); 200 HashSet<OsmPrimitive> newSel = new HashSet<OsmPrimitive>(); 201 for (String item : selection.split(",")) { 202 if (item.startsWith("way")) { 203 ways.add(Long.parseLong(item.substring(3))); 204 } else if (item.startsWith("node")) { 205 nodes.add(Long.parseLong(item.substring(4))); 206 } else if (item.startsWith("relation")) { 207 relations.add(Long.parseLong(item.substring(8))); 208 } else if (item.startsWith("rel")) { 209 relations.add(Long.parseLong(item.substring(3))); 210 } else { 211 System.out.println("RemoteControl: invalid selection '"+item+"' ignored"); 212 } 213 } 214 DataSet ds = Main.main.getCurrentDataSet(); 215 if(ds == null) // e.g. download failed 216 return; 217 for (Way w : ds.getWays()) if (ways.contains(w.getId())) newSel.add(w); 218 for (Node n : ds.getNodes()) if (nodes.contains(n.getId())) newSel.add(n); 219 for (Relation r : ds.getRelations()) if (relations.contains(r.getId())) newSel.add(r); 220 ds.setSelected(newSel); 221 if (Main.pref.getBoolean("remotecontrol.permission.change-viewport", true)) 222 new AutoScaleAction("selection").actionPerformed(null); 223 } 224 }); 225 } else if (Main.pref.getBoolean("remotecontrol.permission.change-viewport", true)) { 226 // after downloading, zoom to downloaded area. 227 final Bounds bounds = new Bounds(new LatLon(minlat, minlon), 228 new LatLon(maxlat, maxlon)); 229 230 // make sure this isn't called unless there *is* a MapView 231 // 232 if (Main.map != null && Main.map.mapView != null) { 233 Main.worker.execute(new Runnable() { 234 public void run() { 235 BoundingXYVisitor bbox = new BoundingXYVisitor(); 236 bbox.visit(bounds); 237 Main.map.mapView.recalculateCenterScale(bbox); 238 } 239 }); 240 } 241 } 242 } else if (command.equals("/add_node")) { 243 if (!Main.pref.getBoolean("remotecontrol.permission.create-objects", true)) { 244 sendForbidden(out); 245 return; 246 } 247 if (Main.pref.getBoolean("remotecontrol.always-confirm", false)) { 248 if (JOptionPane.showConfirmDialog(Main.parent, 249 "<html>" + tr("Remote Control has been asked to create a new node.") + 250 "<br>" + tr("Do you want to allow this?"), 251 tr("Confirm Remote Control action"), 252 JOptionPane.YES_NO_OPTION) != JOptionPane.YES_OPTION) { 253 sendForbidden(out); 254 return; 255 } 256 } 257 addNode(args, out); 258 } else if (command.equals("/import")) { 259 if (Main.pref.getBoolean("remotecontrol.always-confirm", false)) { 260 if (JOptionPane.showConfirmDialog(Main.parent, 261 "<html>" + tr("Remote Control has been asked to import data from the following URL:") + 262 "<br>" + url + 263 "<br>" + tr("Do you want to allow this?"), 264 tr("Confirm Remote Control action"), 265 JOptionPane.YES_NO_OPTION) != JOptionPane.YES_OPTION) { 266 sendForbidden(out); 267 return; 268 } 269 } 270 if (!(args.containsKey("url"))) { 271 sendBadRequest(out); 272 System.out.println("'import' remote control request must have url parameter"); 273 return; 274 } 275 try { 276 if (!Main.pref.getBoolean("remotecontrol.permission.import", true)) 277 throw new LoadDeniedException(); 278 279 DownloadTask osmTask = new DownloadOsmTask(); 280 osmTask.loadUrl(false, URLDecoder.decode(args.get("url"), "UTF-8"), null); 281 } catch (LoadDeniedException ex) { 282 System.out.println("RemoteControl: import forbidden by preferences"); 283 } catch (Exception ex) { 284 sendError(out); 285 System.out.println("RemoteControl: Error parsing import remote control request:"); 286 ex.printStackTrace(); 287 return; 288 } 289 // TODO: select/zoom to downloaded 290 } else if (command.equals("/version")) { 291 if (!Main.pref.getBoolean("remotecontrol.permission.read-protocolversion", true)) { 292 sendForbidden(out); 293 System.out.println("RemoteControl: /version forbidden by preferences"); 294 return; 295 } 296 if (Main.pref.getBoolean("remotecontrol.always-confirm", false)) { 297 if (JOptionPane.showConfirmDialog(Main.parent, 298 "<html>" + tr("Remote Control has been asked to report its protocol version. This enables web sites to detect a running JOSM.") + 299 "<br>" + tr("Do you want to allow this?"), 300 tr("Confirm Remote Control action"), 301 JOptionPane.YES_NO_OPTION) != JOptionPane.YES_OPTION) { 302 sendForbidden(out); 303 return; 304 } 305 } 306 307 content = RequestProcessor.PROTOCOLVERSION; 308 contentType = "application/json"; 309 if (args.containsKey("jsonp")) { 310 content = args.get("jsonp")+ " && " + args.get("jsonp") + "(" + content + ")"; 32 /** The socket this processor listens on */ 33 private Socket request; 34 35 /** 36 * Collection of request handlers. 37 * Will be initialized with default handlers here. Other plug-ins 38 * can extend this list by using @see addRequestHandler 39 */ 40 private static HashMap<String, Class<? extends RequestHandler>> handlers = new HashMap<String, Class<? extends RequestHandler>>(); 41 42 /** 43 * Constructor 44 * 45 * @param request A socket to read the request. 46 */ 47 public RequestProcessor(Socket request) { 48 super("RemoteControl request processor"); 49 this.setDaemon(true); 50 this.request = request; 51 } 52 53 /** 54 * Spawns a new thread for the request 55 * 56 * @param request 57 * The WMS request 58 */ 59 public static void processRequest(Socket request) { 60 RequestProcessor processor = new RequestProcessor(request); 61 processor.start(); 62 } 63 64 /** 65 * Add external request handler. Can be used by other plug-ins that 66 * want to use remote control. 67 * @param command The command to handle. 68 * @param handler The additional request handler. 69 */ 70 static void addRequestHandlerClass(String command, 71 Class<? extends RequestHandler> handler) { 72 addRequestHandlerClass(command, handler, false); 73 } 74 75 /** 76 * Add external request handler. Message can be suppressed. 77 * (for internal use) 78 * @param command The command to handle. 79 * @param handler The additional request handler. 80 * @param silent Don't show message if true. 81 */ 82 private static void addRequestHandlerClass(String command, 83 Class<? extends RequestHandler> handler, boolean silent) { 84 if (handlers.get(command) != null) { 85 System.out.println("RemoteControl: duplicate command " + command 86 + " with handler " + handler.getName()); 87 } else { 88 if(!silent) System.out.println("RemoteControl: adding command command " + 89 command + " (handled by " + handler.getName() + ")"); 90 handlers.put(command, handler); 91 } 92 } 93 94 /** Add default request handlers */ 95 static { 96 addRequestHandlerClass(LoadAndZoomHandler.command, 97 LoadAndZoomHandler.class, true); 98 addRequestHandlerClass(AddNodeHandler.command, AddNodeHandler.class, true); 99 addRequestHandlerClass(ImportHandler.command, ImportHandler.class, true); 100 addRequestHandlerClass(VersionHandler.command, VersionHandler.class, true); 101 } 102 103 /** 104 * The work is done here. 105 */ 106 public void run() { 107 Writer out = null; 108 try { 109 OutputStream raw = new BufferedOutputStream( 110 request.getOutputStream()); 111 out = new OutputStreamWriter(raw); 112 Reader in = new InputStreamReader(new BufferedInputStream( 113 request.getInputStream()), "ASCII"); 114 115 StringBuffer requestLine = new StringBuffer(); 116 while (requestLine.length() < 1024) { 117 int c = in.read(); 118 if (c == '\r' || c == '\n') 119 break; 120 requestLine.append((char) c); 121 } 122 123 System.out.println("RemoteControl received: " + requestLine); 124 String get = requestLine.toString(); 125 StringTokenizer st = new StringTokenizer(get); 126 if (!st.hasMoreTokens()) { 127 sendError(out); 128 return; 129 } 130 String method = st.nextToken(); 131 if (!st.hasMoreTokens()) { 132 sendError(out); 133 return; 134 } 135 String url = st.nextToken(); 136 137 if (!method.equals("GET")) { 138 sendNotImplemented(out); 139 return; 140 } 141 142 String command = null; 143 int questionPos = url.indexOf('?'); 144 if(questionPos < 0) 145 { 146 command = url; 147 } 148 else 149 { 150 command = url.substring(0, questionPos); 151 } 152 153 // find a handler for this command 154 Class<? extends RequestHandler> handlerClass = handlers 155 .get(command); 156 if (handlerClass == null) { 157 // no handler found 158 sendBadRequest(out); 159 } else { 160 // create handler object 161 RequestHandler handler = handlerClass.newInstance(); 162 try { 163 handler.setCommand(command); 164 handler.setUrl(url); 165 handler.checkPermission(); 166 handler.handle(); 167 sendHeader(out, "200 OK", handler.contentType, false); 168 out.write("Content-length: " + handler.content.length() 169 + "\r\n"); 170 out.write("\r\n"); 171 out.write(handler.content); 172 out.flush(); 173 } catch (RequestHandlerErrorException ex) { 174 sendError(out); 175 } catch (RequestHandlerBadRequestException ex) { 176 sendBadRequest(out); 177 } catch (RequestHandlerForbiddenException ex) { 178 sendForbidden(out); 311 179 } 312 180 } 313 sendHeader(out, "200 OK", contentType, false); 314 out.write("Content-length: "+content.length()+"\r\n"); 315 out.write("\r\n"); 316 out.write(content); 317 out.flush(); 318 } 319 catch (IOException ioe) { } 320 catch(Exception e) { 321 e.printStackTrace(); 322 try { 323 sendError(out); 324 } catch (IOException e1) { } 325 } finally { 326 try { 327 request.close(); 328 } catch (IOException e) {} 329 } 330 } 331 332 /** 333 * Adds a node, reacts to the GET /add_node?lon=...&lat=... request. 334 * @param args 335 * @param out 336 * @throws IOException 337 */ 338 private void addNode(HashMap<String, String> args, Writer out) throws IOException { 339 if(!args.containsKey("lat") || !args.containsKey("lon")) { 340 sendBadRequest(out); 341 return; 342 } 343 344 // Parse the arguments 345 double lat = Double.parseDouble(args.get("lat")); 346 double lon = Double.parseDouble(args.get("lon")); 347 System.out.println("Adding node at (" + lat + ", " + lon + ")"); 348 349 // Create a new node 350 LatLon ll = new LatLon(lat, lon); 351 Node nnew = new Node(ll); 352 353 // Now execute the commands to add this node. 354 Main.main.undoRedo.add(new AddCommand(nnew)); 355 Main.main.getCurrentDataSet().setSelected(nnew); 356 Main.map.mapView.repaint(); 357 358 } 359 360 /** 361 * Sends a 500 error: server error 362 * @param out The writer where the error is written 363 * @throws IOException If the error can not be written 364 */ 365 private void sendError(Writer out) throws IOException 366 { 367 sendHeader(out, "500 Internal Server Error", "text/html", true); 368 out.write("<HTML>\r\n"); 369 out.write("<HEAD><TITLE>Internal Error</TITLE>\r\n"); 370 out.write("</HEAD>\r\n"); 371 out.write("<BODY>"); 372 out.write("<H1>HTTP Error 500: Internal Server Error</h2>\r\n"); 373 out.write("</BODY></HTML>\r\n"); 374 out.flush(); 375 } 376 377 /** 378 * Sends a 501 error: not implemented 379 * @param out The writer where the error is written 380 * @throws IOException If the error can not be written 381 */ 382 private void sendNotImplemented(Writer out) throws IOException 383 { 384 sendHeader(out, "501 Not Implemented", "text/html", true); 385 out.write("<HTML>\r\n"); 386 out.write("<HEAD><TITLE>Not Implemented</TITLE>\r\n"); 387 out.write("</HEAD>\r\n"); 388 out.write("<BODY>"); 389 out.write("<H1>HTTP Error 501: Not Implemented</h2>\r\n"); 390 out.write("</BODY></HTML>\r\n"); 391 out.flush(); 392 } 393 394 /** 395 * Sends a 403 error: forbidden 396 * @param out The writer where the error is written 397 * @throws IOException If the error can not be written 398 */ 399 private void sendForbidden(Writer out) throws IOException 400 { 401 sendHeader(out, "403 Forbidden", "text/html", true); 402 out.write("<HTML>\r\n"); 403 out.write("<HEAD><TITLE>Forbidden</TITLE>\r\n"); 404 out.write("</HEAD>\r\n"); 405 out.write("<BODY>"); 406 out.write("<H1>HTTP Error 403: Forbidden</h2>\r\n"); 407 out.write("</BODY></HTML>\r\n"); 408 out.flush(); 409 } 410 /** 411 * Sends a 403 error: forbidden 412 * @param out The writer where the error is written 413 * @throws IOException If the error can not be written 414 */ 415 private void sendBadRequest(Writer out) throws IOException 416 { 417 sendHeader(out, "400 Bad Request", "text/html", true); 418 out.write("<HTML>\r\n"); 419 out.write("<HEAD><TITLE>Bad Request</TITLE>\r\n"); 420 out.write("</HEAD>\r\n"); 421 out.write("<BODY>"); 422 out.write("<H1>HTTP Error 400: Bad Request</h2>\r\n"); 423 out.write("</BODY></HTML>\r\n"); 424 out.flush(); 425 } 426 427 /** 428 * Send common HTTP headers to the client. 429 * 430 * @param out The Writer 431 * @param status The status string ("200 OK", "500", etc) 432 * @param contentType The content type of the data sent 433 * @param endHeaders If true, adds a new line, ending the headers. 434 * @throws IOException When error 435 */ 436 private void sendHeader(Writer out, String status, String contentType, boolean endHeaders) throws IOException 437 { 438 out.write("HTTP/1.1 " + status + "\r\n"); 439 Date now = new Date(); 440 out.write("Date: " + now + "\r\n"); 441 out.write("Server: JOSM RemoteControl\r\n"); 442 out.write("Content-type: " + contentType + "\r\n"); 181 182 } catch (IOException ioe) { 183 } catch (Exception e) { 184 e.printStackTrace(); 185 try { 186 sendError(out); 187 } catch (IOException e1) { 188 } 189 } finally { 190 try { 191 request.close(); 192 } catch (IOException e) { 193 } 194 } 195 } 196 197 /** 198 * Sends a 500 error: server error 199 * 200 * @param out 201 * The writer where the error is written 202 * @throws IOException 203 * If the error can not be written 204 */ 205 private void sendError(Writer out) throws IOException { 206 sendHeader(out, "500 Internal Server Error", "text/html", true); 207 out.write("<HTML>\r\n"); 208 out.write("<HEAD><TITLE>Internal Error</TITLE>\r\n"); 209 out.write("</HEAD>\r\n"); 210 out.write("<BODY>"); 211 out.write("<H1>HTTP Error 500: Internal Server Error</h2>\r\n"); 212 out.write("</BODY></HTML>\r\n"); 213 out.flush(); 214 } 215 216 /** 217 * Sends a 501 error: not implemented 218 * 219 * @param out 220 * The writer where the error is written 221 * @throws IOException 222 * If the error can not be written 223 */ 224 private void sendNotImplemented(Writer out) throws IOException { 225 sendHeader(out, "501 Not Implemented", "text/html", true); 226 out.write("<HTML>\r\n"); 227 out.write("<HEAD><TITLE>Not Implemented</TITLE>\r\n"); 228 out.write("</HEAD>\r\n"); 229 out.write("<BODY>"); 230 out.write("<H1>HTTP Error 501: Not Implemented</h2>\r\n"); 231 out.write("</BODY></HTML>\r\n"); 232 out.flush(); 233 } 234 235 /** 236 * Sends a 403 error: forbidden 237 * 238 * @param out 239 * The writer where the error is written 240 * @throws IOException 241 * If the error can not be written 242 */ 243 private void sendForbidden(Writer out) throws IOException { 244 sendHeader(out, "403 Forbidden", "text/html", true); 245 out.write("<HTML>\r\n"); 246 out.write("<HEAD><TITLE>Forbidden</TITLE>\r\n"); 247 out.write("</HEAD>\r\n"); 248 out.write("<BODY>"); 249 out.write("<H1>HTTP Error 403: Forbidden</h2>\r\n"); 250 out.write("</BODY></HTML>\r\n"); 251 out.flush(); 252 } 253 254 /** 255 * Sends a 403 error: forbidden 256 * 257 * @param out 258 * The writer where the error is written 259 * @throws IOException 260 * If the error can not be written 261 */ 262 private void sendBadRequest(Writer out) throws IOException { 263 sendHeader(out, "400 Bad Request", "text/html", true); 264 out.write("<HTML>\r\n"); 265 out.write("<HEAD><TITLE>Bad Request</TITLE>\r\n"); 266 out.write("</HEAD>\r\n"); 267 out.write("<BODY>"); 268 out.write("<H1>HTTP Error 400: Bad Request</h2>\r\n"); 269 out.write("</BODY></HTML>\r\n"); 270 out.flush(); 271 } 272 273 /** 274 * Send common HTTP headers to the client. 275 * 276 * @param out 277 * The Writer 278 * @param status 279 * The status string ("200 OK", "500", etc) 280 * @param contentType 281 * The content type of the data sent 282 * @param endHeaders 283 * If true, adds a new line, ending the headers. 284 * @throws IOException 285 * When error 286 */ 287 private void sendHeader(Writer out, String status, String contentType, 288 boolean endHeaders) throws IOException { 289 out.write("HTTP/1.1 " + status + "\r\n"); 290 Date now = new Date(); 291 out.write("Date: " + now + "\r\n"); 292 out.write("Server: JOSM RemoteControl\r\n"); 293 out.write("Content-type: " + contentType + "\r\n"); 443 294 out.write("Access-Control-Allow-Origin: *\r\n"); 444 445 446 295 if (endHeaders) 296 out.write("\r\n"); 297 } 447 298 }
Note:
See TracChangeset
for help on using the changeset viewer.