Ticket #13187: 59c2a1c268fc1f309258b75729b5bd450331ec22.patch

File 59c2a1c268fc1f309258b75729b5bd450331ec22.patch, 7.3 KB (added by floscher, 4 years ago)
  • src/org/openstreetmap/josm/io/remotecontrol/RequestProcessor.java

    From 59c2a1c268fc1f309258b75729b5bd450331ec22 Mon Sep 17 00:00:00 2001
    From: =?UTF-8?q?Florian=20Sch=C3=A4fer?= <florian@schaeferban.de>
    Date: Fri, 22 Jul 2016 15:00:41 +0200
    Subject: [PATCH] Fix encoding and HTML-escaping of the error pages of the
     remote control
    
    This ensures that special characters on the error pages of the remote control are shown correctly in the users browser.
    Setting the encoding to UTF-8 in the HTTP-header and in HTML ensures that browsers will recognize that the page is encoded in UTF-8 and display special characters correctly.
    And the localized error messages are now escaped, so that they are displayed correctly even when they contain special characters like <, > or &.
    ---
     .../josm/io/remotecontrol/RequestProcessor.java    | 68 +++++++++++-----------
     .../io/remotecontrol/handler/RequestHandler.java   |  5 +-
     2 files changed, 36 insertions(+), 37 deletions(-)
    
    diff --git a/src/org/openstreetmap/josm/io/remotecontrol/RequestProcessor.java b/src/org/openstreetmap/josm/io/remotecontrol/RequestProcessor.java
    index 85dd37c..f40608f 100644
    a b  
    1111import java.io.StringWriter;
    1212import java.io.Writer;
    1313import java.net.Socket;
     14import java.nio.charset.Charset;
    1415import java.nio.charset.StandardCharsets;
    1516import java.util.Arrays;
    1617import java.util.Date;
     
    4445 * Processes HTTP "remote control" requests.
    4546 */
    4647public class RequestProcessor extends Thread {
     48
     49    private static final Charset RESPONSE_CHARSET = StandardCharsets.UTF_8;
     50    private static final String RESPONSE_TEMPLATE = "<!DOCTYPE html><html><head><meta charset=\""
     51            + RESPONSE_CHARSET.name()
     52            + "\">%s</head><body>%s</body></html>";
     53
    4754    /**
    4855     * RemoteControl protocol version. Change minor number for compatible
    4956     * interface extensions. Change major number in case of incompatible
    public void run() { 
    144151        Writer out = null;
    145152        try {
    146153            OutputStream raw = new BufferedOutputStream(request.getOutputStream());
    147             out = new OutputStreamWriter(raw, StandardCharsets.UTF_8);
     154            out = new OutputStreamWriter(raw, RESPONSE_CHARSET);
    148155            BufferedReader in = new BufferedReader(new InputStreamReader(request.getInputStream(), "ASCII"));
    149156
    150157            String get = in.readLine();
    public void run() { 
    268275     */
    269276    private static void sendError(Writer out) throws IOException {
    270277        sendHeader(out, "500 Internal Server Error", "text/html", true);
    271         out.write("<HTML>\r\n");
    272         out.write("<HEAD><TITLE>Internal Error</TITLE>\r\n");
    273         out.write("</HEAD>\r\n");
    274         out.write("<BODY>");
    275         out.write("<H1>HTTP Error 500: Internal Server Error</H1>\r\n");
    276         out.write("</BODY></HTML>\r\n");
     278        out.write(String.format(
     279                RESPONSE_TEMPLATE,
     280                "<title>Internal Error</title>",
     281                "<h1>HTTP Error 500: Internal Server Error</h1>"
     282        ));
    277283        out.flush();
    278284    }
    279285
    private static void sendError(Writer out) throws IOException { 
    287293     */
    288294    private static void sendNotImplemented(Writer out) throws IOException {
    289295        sendHeader(out, "501 Not Implemented", "text/html", true);
    290         out.write("<HTML>\r\n");
    291         out.write("<HEAD><TITLE>Not Implemented</TITLE>\r\n");
    292         out.write("</HEAD>\r\n");
    293         out.write("<BODY>");
    294         out.write("<H1>HTTP Error 501: Not Implemented</h2>\r\n");
    295         out.write("</BODY></HTML>\r\n");
     296        out.write(String.format(
     297                RESPONSE_TEMPLATE,
     298                "<title>Not Implemented</title>",
     299                "<h1>HTTP Error 501: Not Implemented</h1>"
     300        ));
    296301        out.flush();
    297302    }
    298303
    private static void sendNotImplemented(Writer out) throws IOException { 
    308313     */
    309314    private static void sendForbidden(Writer out, String help) throws IOException {
    310315        sendHeader(out, "403 Forbidden", "text/html", true);
    311         out.write("<HTML>\r\n");
    312         out.write("<HEAD><TITLE>Forbidden</TITLE>\r\n");
    313         out.write("</HEAD>\r\n");
    314         out.write("<BODY>");
    315         out.write("<H1>HTTP Error 403: Forbidden</h2>\r\n");
    316         if (help != null) {
    317             out.write(help);
    318         }
    319         out.write("</BODY></HTML>\r\n");
     316        out.write(String.format(
     317                RESPONSE_TEMPLATE,
     318                "<title>Forbidden</title>",
     319                "<h1>HTTP Error 403: Forbidden</h1>" +
     320                (help == null ? "" : "<p>"+Utils.escapeReservedCharactersHTML(help) + "</p>")
     321        ));
    320322        out.flush();
    321323    }
    322324
    323325    /**
    324      * Sends a 403 error: forbidden
     326     * Sends a 400 error: bad request
    325327     *
    326328     * @param out
    327329     *            The writer where the error is written
    private static void sendForbidden(Writer out, String help) throws IOException { 
    332334     */
    333335    private static void sendBadRequest(Writer out, String help) throws IOException {
    334336        sendHeader(out, "400 Bad Request", "text/html", true);
    335         out.write("<HTML>\r\n");
    336         out.write("<HEAD><TITLE>Bad Request</TITLE>\r\n");
    337         out.write("</HEAD>\r\n");
    338         out.write("<BODY>");
    339         out.write("<H1>HTTP Error 400: Bad Request</h2>\r\n");
    340         if (help != null) {
    341             out.write(help);
    342         }
    343         out.write("</BODY></HTML>\r\n");
     337        out.write(String.format(
     338                RESPONSE_TEMPLATE,
     339                "<title>Bad Request</title>",
     340                "<h1>HTTP Error 400: Bad Request</h1>" +
     341                (help == null ? "" : "<p>"+Utils.escapeReservedCharactersHTML(help) + "</p>")
     342        ));
    344343        out.flush();
    345344    }
    346345
    private static void sendBadRequest(Writer out, String help) throws IOException { 
    361360    private static void sendHeader(Writer out, String status, String contentType,
    362361            boolean endHeaders) throws IOException {
    363362        out.write("HTTP/1.1 " + status + "\r\n");
    364         Date now = new Date();
    365         out.write("Date: " + now + "\r\n");
     363        out.write("Date: " + new Date() + "\r\n");
    366364        out.write("Server: JOSM RemoteControl\r\n");
    367         out.write("Content-type: " + contentType + "\r\n");
     365        out.write("Content-type: " + contentType + "; charset=" + RESPONSE_CHARSET.name().toLowerCase() + "\r\n");
    368366        out.write("Access-Control-Allow-Origin: *\r\n");
    369367        if (endHeaders)
    370368            out.write("\r\n");
  • src/org/openstreetmap/josm/io/remotecontrol/handler/RequestHandler.java

    diff --git a/src/org/openstreetmap/josm/io/remotecontrol/handler/RequestHandler.java b/src/org/openstreetmap/josm/io/remotecontrol/handler/RequestHandler.java
    index 6aaa417..a906d26 100644
    a b void checkMandatoryParams() throws RequestHandlerBadRequestException { 
    246246        }
    247247        if (error) {
    248248            throw new RequestHandlerBadRequestException(
    249                     "The following keys are mandatory, but have not been provided: "
    250                     + Utils.join(", ", missingKeys));
     249                    tr("The following keys are mandatory, but have not been provided: {0}",
     250                            Utils.join(", ", missingKeys))
     251            );
    251252        }
    252253    }
    253254