Ignore:
Timestamp:
2010-08-17T22:52:49+02:00 (14 years ago)
Author:
bomm
Message:

separate all existing remote commands as individual handlers
allow other plug-ins to register additional handlers

Location:
applications/editors/josm/plugins/remotecontrol/src/org/openstreetmap/josm/plugins/remotecontrol
Files:
11 added
3 edited

Legend:

Unmodified
Added
Removed
  • applications/editors/josm/plugins/remotecontrol/src/org/openstreetmap/josm/plugins/remotecontrol/RemoteControlPlugin.java

    r19471 r22675  
    2121    {
    2222        super(info);
     23        /*
     24                System.out.println("constructor " + this.getClass().getName() + " (" + info.name +
     25                                " v " + info.version + " stage " + info.stage + ")");
     26                */
    2327        restartServer();
    2428    }
     
    5054        }
    5155    }
     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   
    5268}
  • applications/editors/josm/plugins/remotecontrol/src/org/openstreetmap/josm/plugins/remotecontrol/RemoteControlPreferences.java

    r22479 r22675  
    1313
    1414import org.openstreetmap.josm.Main;
    15 import org.openstreetmap.josm.gui.preferences.PreferenceDialog;
    1615import org.openstreetmap.josm.gui.preferences.PreferenceSetting;
    1716import org.openstreetmap.josm.gui.preferences.PreferenceTabbedPane;
  • applications/editors/josm/plugins/remotecontrol/src/org/openstreetmap/josm/plugins/remotecontrol/RequestProcessor.java

    r22479 r22675  
    11package org.openstreetmap.josm.plugins.remotecontrol;
    22
    3 import static org.openstreetmap.josm.tools.I18n.tr;
    4 
    5 import java.awt.geom.Area;
    6 import java.awt.geom.Rectangle2D;
    73import java.io.BufferedInputStream;
    84import java.io.BufferedOutputStream;
     
    1410import java.io.Writer;
    1511import java.net.Socket;
    16 import java.net.URLDecoder;
    1712import java.util.Date;
    1813import java.util.HashMap;
    19 import java.util.HashSet;
    2014import 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
     16import org.openstreetmap.josm.plugins.remotecontrol.handler.AddNodeHandler;
     17import org.openstreetmap.josm.plugins.remotecontrol.handler.ImportHandler;
     18import org.openstreetmap.josm.plugins.remotecontrol.handler.LoadAndZoomHandler;
     19import org.openstreetmap.josm.plugins.remotecontrol.handler.VersionHandler;
    3920
    4021/**
    4122 * Processes HTTP "remote control" requests.
    4223 */
    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 incompatible changes.
     24public 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.
    4829         */
    4930        public static final String PROTOCOLVERSION = "{\"protocolversion\": {\"major\": 1, \"minor\": 0}, \"application\": \"JOSM RemoteControl\"}";
    5031
    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);
    311179                                }
    312180                        }
    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=...&amp;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");
    443294                out.write("Access-Control-Allow-Origin: *\r\n");
    444         if (endHeaders)
    445             out.write("\r\n");
    446     }
     295                if (endHeaders)
     296                        out.write("\r\n");
     297        }
    447298}
Note: See TracChangeset for help on using the changeset viewer.