Ticket #13187: 776bb6d8b1a0e35492151835f7ac612ede1f8596.patch

File 776bb6d8b1a0e35492151835f7ac612ede1f8596.patch, 6.8 KB (added by floscher, 4 years ago)
  • src/org/openstreetmap/josm/io/remotecontrol/RequestProcessor.java

    From 776bb6d8b1a0e35492151835f7ac612ede1f8596 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    | 52 +++++++++-------------
     .../io/remotecontrol/handler/RequestHandler.java   |  2 +-
     2 files changed, 23 insertions(+), 31 deletions(-)
    
    diff --git a/src/org/openstreetmap/josm/io/remotecontrol/RequestProcessor.java b/src/org/openstreetmap/josm/io/remotecontrol/RequestProcessor.java
    index 85dd37c..a6c3435 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 BASIC_HTML_HEAD = "<!DOCTYPE html><meta charset=\"" + RESPONSE_CHARSET.name() + "\">";
     51
    4752    /**
    4853     * RemoteControl protocol version. Change minor number for compatible
    4954     * interface extensions. Change major number in case of incompatible
    public void run() { 
    144149        Writer out = null;
    145150        try {
    146151            OutputStream raw = new BufferedOutputStream(request.getOutputStream());
    147             out = new OutputStreamWriter(raw, StandardCharsets.UTF_8);
     152            out = new OutputStreamWriter(raw, RESPONSE_CHARSET);
    148153            BufferedReader in = new BufferedReader(new InputStreamReader(request.getInputStream(), "ASCII"));
    149154
    150155            String get = in.readLine();
    public void run() { 
    268273     */
    269274    private static void sendError(Writer out) throws IOException {
    270275        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");
     276        out.write(BASIC_HTML_HEAD);
     277        out.write("<title>Internal Error</title>");
     278        out.write("<h1>HTTP Error 500: Internal Server Error</h1>");
    277279        out.flush();
    278280    }
    279281
    private static void sendError(Writer out) throws IOException { 
    287289     */
    288290    private static void sendNotImplemented(Writer out) throws IOException {
    289291        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");
     292        out.write(BASIC_HTML_HEAD);
     293        out.write("<title>Not Implemented</title>");
     294        out.write("<h1>HTTP Error 501: Not Implemented</h1>");
    296295        out.flush();
    297296    }
    298297
    private static void sendNotImplemented(Writer out) throws IOException { 
    308307     */
    309308    private static void sendForbidden(Writer out, String help) throws IOException {
    310309        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");
     310        out.write(BASIC_HTML_HEAD);
     311        out.write("<title>Forbidden</title>");
     312        out.write("<h1>HTTP Error 403: Forbidden</h1>");
    316313        if (help != null) {
    317             out.write(help);
     314            out.write("<p>" + Utils.escapeReservedCharactersHTML(help) + "</p>");
    318315        }
    319         out.write("</BODY></HTML>\r\n");
    320316        out.flush();
    321317    }
    322318
    private static void sendForbidden(Writer out, String help) throws IOException { 
    332328     */
    333329    private static void sendBadRequest(Writer out, String help) throws IOException {
    334330        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");
     331        out.write(BASIC_HTML_HEAD);
     332        out.write("<title>Bad Request</title>");
     333        out.write("<h1>HTTP Error 400: Bad Request</h1>");
    340334        if (help != null) {
    341             out.write(help);
     335            out.write("<p>" + Utils.escapeReservedCharactersHTML(help) + "</p>");
    342336        }
    343         out.write("</BODY></HTML>\r\n");
    344337        out.flush();
    345338    }
    346339
    private static void sendBadRequest(Writer out, String help) throws IOException { 
    361354    private static void sendHeader(Writer out, String status, String contentType,
    362355            boolean endHeaders) throws IOException {
    363356        out.write("HTTP/1.1 " + status + "\r\n");
    364         Date now = new Date();
    365         out.write("Date: " + now + "\r\n");
     357        out.write("Date: " + new Date() + "\r\n");
    366358        out.write("Server: JOSM RemoteControl\r\n");
    367         out.write("Content-type: " + contentType + "\r\n");
     359        out.write("Content-type: " + contentType + "; charset=" + RESPONSE_CHARSET.name().toLowerCase() + "\r\n");
    368360        out.write("Access-Control-Allow-Origin: *\r\n");
    369361        if (endHeaders)
    370362            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..105599e 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: "
     249                    tr("The following keys are mandatory, but have not been provided:") + ' '
    250250                    + Utils.join(", ", missingKeys));
    251251        }
    252252    }