You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@tomcat.apache.org by vi...@apache.org on 2017/03/27 10:38:29 UTC

svn commit: r1788881 - in /tomcat/tc8.5.x/trunk: java/org/apache/coyote/ java/org/apache/coyote/ajp/ java/org/apache/coyote/http11/ java/org/apache/tomcat/util/http/ java/org/apache/tomcat/util/http/res/ test/org/apache/coyote/http11/filters/ test/org/...

Author: violetagg
Date: Mon Mar 27 10:38:29 2017
New Revision: 1788881

URL: http://svn.apache.org/viewvc?rev=1788881&view=rev
Log:
Fix https://bz.apache.org/bugzilla/show_bug.cgi?id=60362
Add a new Connector configuration sendReasonPhrase. When this attribute is set to true, a reason phrase will be sent with the response.
By default a reason phrase will not be sent. This option is deprecated and is not available in Tomcat 9.

Added:
    tomcat/tc8.5.x/trunk/java/org/apache/tomcat/util/http/HttpMessages.java   (with props)
    tomcat/tc8.5.x/trunk/java/org/apache/tomcat/util/http/res/
    tomcat/tc8.5.x/trunk/java/org/apache/tomcat/util/http/res/LocalStrings.properties   (with props)
    tomcat/tc8.5.x/trunk/java/org/apache/tomcat/util/http/res/LocalStrings_es.properties   (with props)
    tomcat/tc8.5.x/trunk/java/org/apache/tomcat/util/http/res/LocalStrings_fr.properties   (with props)
Modified:
    tomcat/tc8.5.x/trunk/java/org/apache/coyote/AbstractProtocol.java
    tomcat/tc8.5.x/trunk/java/org/apache/coyote/Constants.java
    tomcat/tc8.5.x/trunk/java/org/apache/coyote/ajp/AbstractAjpProtocol.java
    tomcat/tc8.5.x/trunk/java/org/apache/coyote/ajp/AjpProcessor.java
    tomcat/tc8.5.x/trunk/java/org/apache/coyote/http11/AbstractHttp11Protocol.java
    tomcat/tc8.5.x/trunk/java/org/apache/coyote/http11/Constants.java
    tomcat/tc8.5.x/trunk/java/org/apache/coyote/http11/Http11OutputBuffer.java
    tomcat/tc8.5.x/trunk/java/org/apache/coyote/http11/Http11Processor.java
    tomcat/tc8.5.x/trunk/test/org/apache/coyote/http11/filters/TesterOutputBuffer.java
    tomcat/tc8.5.x/trunk/test/org/apache/tomcat/util/buf/TestByteChunk.java
    tomcat/tc8.5.x/trunk/webapps/docs/changelog.xml
    tomcat/tc8.5.x/trunk/webapps/docs/config/ajp.xml
    tomcat/tc8.5.x/trunk/webapps/docs/config/http.xml
    tomcat/tc8.5.x/trunk/webapps/docs/config/systemprops.xml

Modified: tomcat/tc8.5.x/trunk/java/org/apache/coyote/AbstractProtocol.java
URL: http://svn.apache.org/viewvc/tomcat/tc8.5.x/trunk/java/org/apache/coyote/AbstractProtocol.java?rev=1788881&r1=1788880&r2=1788881&view=diff
==============================================================================
--- tomcat/tc8.5.x/trunk/java/org/apache/coyote/AbstractProtocol.java (original)
+++ tomcat/tc8.5.x/trunk/java/org/apache/coyote/AbstractProtocol.java Mon Mar 27 10:38:29 2017
@@ -207,6 +207,40 @@ public abstract class AbstractProtocol<S
         return asyncTimeout;
     }
 
+    /**
+     * Specifies whether the reason phrase will be sent in the response.
+     * By default a reason phrase will not be sent in the response.
+     * 
+     * @deprecated This option will be removed in Tomcat 9. Reason phrase will
+     *             not be sent.
+     */
+    @Deprecated
+    private boolean sendReasonPhrase = false;
+    /**
+     * Returns whether the reason phrase will be sent in the response.
+     * By default a reason phrase will not be sent in the response.
+     *
+     * @return whether the reason phrase will be sent
+     * @deprecated This option will be removed in Tomcat 9. Reason phrase will
+     *             not be sent.
+     */
+    @Deprecated
+    public boolean getSendReasonPhrase() {
+        return sendReasonPhrase;
+    }
+    /**
+     * Specifies whether the reason phrase will be sent in the response.
+     * By default a reason phrase will not be sent in the response.
+     *
+     * @param sendReasonPhrase specifies whether the reason phrase will be sent
+     * @deprecated This option will be removed in Tomcat 9. Reason phrase will
+     *             not be sent.
+     */
+    @Deprecated
+    public void setSendReasonPhrase(boolean sendReasonPhrase) {
+        this.sendReasonPhrase = sendReasonPhrase;
+    }
+
 
     // ---------------------- Properties that are passed through to the EndPoint
 

Modified: tomcat/tc8.5.x/trunk/java/org/apache/coyote/Constants.java
URL: http://svn.apache.org/viewvc/tomcat/tc8.5.x/trunk/java/org/apache/coyote/Constants.java?rev=1788881&r1=1788880&r2=1788881&view=diff
==============================================================================
--- tomcat/tc8.5.x/trunk/java/org/apache/coyote/Constants.java (original)
+++ tomcat/tc8.5.x/trunk/java/org/apache/coyote/Constants.java Mon Mar 27 10:38:29 2017
@@ -49,6 +49,17 @@ public final class Constants {
 
 
     /**
+     * If true, custom HTTP status messages will be used in headers.
+     * @deprecated This option will be removed in Tomcat 9. Reason phrase will
+     *             not be sent.
+     */
+    @Deprecated
+    public static final boolean USE_CUSTOM_STATUS_MSG_IN_HEADER =
+        Boolean.valueOf(System.getProperty(
+                "org.apache.coyote.USE_CUSTOM_STATUS_MSG_IN_HEADER",
+                "false")).booleanValue();
+
+    /**
      * The request attribute that is set to the value of {@code Boolean.TRUE}
      * if connector processing this request supports use of sendfile.
      */

Modified: tomcat/tc8.5.x/trunk/java/org/apache/coyote/ajp/AbstractAjpProtocol.java
URL: http://svn.apache.org/viewvc/tomcat/tc8.5.x/trunk/java/org/apache/coyote/ajp/AbstractAjpProtocol.java?rev=1788881&r1=1788880&r2=1788881&view=diff
==============================================================================
--- tomcat/tc8.5.x/trunk/java/org/apache/coyote/ajp/AbstractAjpProtocol.java (original)
+++ tomcat/tc8.5.x/trunk/java/org/apache/coyote/ajp/AbstractAjpProtocol.java Mon Mar 27 10:38:29 2017
@@ -182,6 +182,7 @@ public abstract class AbstractAjpProtoco
     }
 
 
+    @SuppressWarnings("deprecation")
     @Override
     protected Processor createProcessor() {
         AjpProcessor processor = new AjpProcessor(getPacketSize(), getEndpoint());
@@ -192,6 +193,7 @@ public abstract class AbstractAjpProtoco
         processor.setRequiredSecret(requiredSecret);
         processor.setKeepAliveTimeout(getKeepAliveTimeout());
         processor.setClientCertProvider(getClientCertProvider());
+        processor.setSendReasonPhrase(getSendReasonPhrase());
         return processor;
     }
 

Modified: tomcat/tc8.5.x/trunk/java/org/apache/coyote/ajp/AjpProcessor.java
URL: http://svn.apache.org/viewvc/tomcat/tc8.5.x/trunk/java/org/apache/coyote/ajp/AjpProcessor.java?rev=1788881&r1=1788880&r2=1788881&view=diff
==============================================================================
--- tomcat/tc8.5.x/trunk/java/org/apache/coyote/ajp/AjpProcessor.java (original)
+++ tomcat/tc8.5.x/trunk/java/org/apache/coyote/ajp/AjpProcessor.java Mon Mar 27 10:38:29 2017
@@ -40,6 +40,7 @@ import org.apache.tomcat.util.ExceptionU
 import org.apache.tomcat.util.buf.ByteChunk;
 import org.apache.tomcat.util.buf.HexUtils;
 import org.apache.tomcat.util.buf.MessageBytes;
+import org.apache.tomcat.util.http.HttpMessages;
 import org.apache.tomcat.util.http.MimeHeaders;
 import org.apache.tomcat.util.net.AbstractEndpoint;
 import org.apache.tomcat.util.net.AbstractEndpoint.Handler.SocketState;
@@ -346,6 +347,13 @@ public class AjpProcessor extends Abstra
         this.clientCertProvider = clientCertProvider;
     }
 
+    @Deprecated
+    private boolean sendReasonPhrase = false;
+    @Deprecated
+    void setSendReasonPhrase(boolean sendReasonPhrase) {
+        this.sendReasonPhrase = sendReasonPhrase;
+    }
+
 
     // --------------------------------------------------------- Public Methods
 
@@ -1008,6 +1016,7 @@ public class AjpProcessor extends Abstra
      * When committing the response, we have to validate the set of headers, as
      * well as setup the response filters.
      */
+    @SuppressWarnings("deprecation")
     @Override
     protected final void prepareResponse() throws IOException {
 
@@ -1037,9 +1046,26 @@ public class AjpProcessor extends Abstra
 
         // HTTP header contents
         responseMessage.appendInt(statusCode);
-        // Reason phrase is optional but mod_jk + httpd 2.x fails with a null
-        // reason phrase - bug 45026
-        tmpMB.setString(Integer.toString(response.getStatus()));
+        if (sendReasonPhrase) {
+            String message = null;
+            if (org.apache.coyote.Constants.USE_CUSTOM_STATUS_MSG_IN_HEADER &&
+                    HttpMessages.isSafeInHttpHeader(response.getMessage())) {
+                message = response.getMessage();
+            }
+            if (message == null) {
+                message = HttpMessages.getInstance(
+                        response.getLocale()).getMessage(response.getStatus());
+            }
+            if (message == null) {
+                // mod_jk + httpd 2.x fails with a null status message - bug 45026
+                message = Integer.toString(response.getStatus());
+            }
+            tmpMB.setString(message);
+        } else {
+            // Reason phrase is optional but mod_jk + httpd 2.x fails with a null
+            // reason phrase - bug 45026
+            tmpMB.setString(Integer.toString(response.getStatus()));
+        }
         responseMessage.appendBytes(tmpMB);
 
         // Special headers

Modified: tomcat/tc8.5.x/trunk/java/org/apache/coyote/http11/AbstractHttp11Protocol.java
URL: http://svn.apache.org/viewvc/tomcat/tc8.5.x/trunk/java/org/apache/coyote/http11/AbstractHttp11Protocol.java?rev=1788881&r1=1788880&r2=1788881&view=diff
==============================================================================
--- tomcat/tc8.5.x/trunk/java/org/apache/coyote/http11/AbstractHttp11Protocol.java (original)
+++ tomcat/tc8.5.x/trunk/java/org/apache/coyote/http11/AbstractHttp11Protocol.java Mon Mar 27 10:38:29 2017
@@ -796,11 +796,12 @@ public abstract class AbstractHttp11Prot
 
     // ------------------------------------------------------------- Common code
 
+    @SuppressWarnings("deprecation")
     @Override
     protected Processor createProcessor() {
         Http11Processor processor = new Http11Processor(getMaxHttpHeaderSize(), getEndpoint(),
                 getMaxTrailerSize(), allowedTrailerHeaders, getMaxExtensionSize(),
-                getMaxSwallowSize(), httpUpgradeProtocols);
+                getMaxSwallowSize(), httpUpgradeProtocols, getSendReasonPhrase());
         processor.setAdapter(getAdapter());
         processor.setMaxKeepAliveRequests(getMaxKeepAliveRequests());
         processor.setConnectionUploadTimeout(getConnectionUploadTimeout());

Modified: tomcat/tc8.5.x/trunk/java/org/apache/coyote/http11/Constants.java
URL: http://svn.apache.org/viewvc/tomcat/tc8.5.x/trunk/java/org/apache/coyote/http11/Constants.java?rev=1788881&r1=1788880&r2=1788881&view=diff
==============================================================================
--- tomcat/tc8.5.x/trunk/java/org/apache/coyote/http11/Constants.java (original)
+++ tomcat/tc8.5.x/trunk/java/org/apache/coyote/http11/Constants.java Mon Mar 27 10:38:29 2017
@@ -107,8 +107,14 @@ public final class Constants {
     public static final String KEEPALIVE = "keep-alive";
     public static final byte[] KEEPALIVE_BYTES = ByteChunk.convertToBytes(KEEPALIVE);
     public static final String CHUNKED = "chunked";
-    public static final byte[] ACK_BYTES =
+    /**
+     * @deprecated This option will be removed in Tomcat 9. Reason phrase will
+     *             not be sent.
+     */
+    @Deprecated
+    public static final byte[] ACK_BYTES_REASON =
             ByteChunk.convertToBytes("HTTP/1.1 100 Continue" + CRLF + CRLF);
+    public static final byte[] ACK_BYTES = ByteChunk.convertToBytes("HTTP/1.1 100 " + CRLF + CRLF);
     public static final String TRANSFERENCODING = "Transfer-Encoding";
     public static final byte[] _200_BYTES = ByteChunk.convertToBytes("200");
     public static final byte[] _400_BYTES = ByteChunk.convertToBytes("400");

Modified: tomcat/tc8.5.x/trunk/java/org/apache/coyote/http11/Http11OutputBuffer.java
URL: http://svn.apache.org/viewvc/tomcat/tc8.5.x/trunk/java/org/apache/coyote/http11/Http11OutputBuffer.java?rev=1788881&r1=1788880&r2=1788881&view=diff
==============================================================================
--- tomcat/tc8.5.x/trunk/java/org/apache/coyote/http11/Http11OutputBuffer.java (original)
+++ tomcat/tc8.5.x/trunk/java/org/apache/coyote/http11/Http11OutputBuffer.java Mon Mar 27 10:38:29 2017
@@ -27,6 +27,7 @@ import org.apache.juli.logging.Log;
 import org.apache.juli.logging.LogFactory;
 import org.apache.tomcat.util.buf.ByteChunk;
 import org.apache.tomcat.util.buf.MessageBytes;
+import org.apache.tomcat.util.http.HttpMessages;
 import org.apache.tomcat.util.net.SocketWrapperBase;
 import org.apache.tomcat.util.res.StringManager;
 
@@ -108,9 +109,14 @@ public class Http11OutputBuffer implemen
     protected long byteCount = 0;
 
 
-    protected Http11OutputBuffer(Response response, int headerBufferSize) {
+    @Deprecated
+    private boolean sendReasonPhrase = false;
+
+
+    protected Http11OutputBuffer(Response response, int headerBufferSize, boolean sendReasonPhrase) {
 
         this.response = response;
+        this.sendReasonPhrase = sendReasonPhrase;
 
         headerBuffer = ByteBuffer.allocate(headerBufferSize);
 
@@ -121,6 +127,11 @@ public class Http11OutputBuffer implemen
         responseFinished = false;
 
         outputStreamOutputBuffer = new SocketOutputBuffer();
+
+        if (sendReasonPhrase) {
+            // Cause loading of HttpMessages
+            HttpMessages.getInstance(response.getLocale()).getMessage(200);
+        }
     }
 
 
@@ -327,9 +338,14 @@ public class Http11OutputBuffer implemen
     }
 
 
+    @SuppressWarnings("deprecation")
     public void sendAck() throws IOException {
         if (!response.isCommitted()) {
-            socketWrapper.write(isBlocking(), Constants.ACK_BYTES, 0, Constants.ACK_BYTES.length);
+            if (sendReasonPhrase) {
+                socketWrapper.write(isBlocking(), Constants.ACK_BYTES_REASON, 0, Constants.ACK_BYTES_REASON.length);
+            } else {
+                socketWrapper.write(isBlocking(), Constants.ACK_BYTES, 0, Constants.ACK_BYTES.length);
+            }
             if (flushBuffer(true)) {
                 throw new IOException(sm.getString("iob.failedwrite.ack"));
             }
@@ -360,6 +376,7 @@ public class Http11OutputBuffer implemen
     /**
      * Send the response status line.
      */
+    @SuppressWarnings("deprecation")
     public void sendStatus() {
         // Write protocol name
         write(Constants.HTTP_11_BYTES);
@@ -383,9 +400,24 @@ public class Http11OutputBuffer implemen
 
         headerBuffer.put(Constants.SP);
 
-        // The reason phrase is optional but the space before it is not. Skip
-        // sending the reason phrase. Clients should ignore it (RFC 7230) and it
-        // just wastes bytes.
+        if (sendReasonPhrase) {
+            // Write message
+            String message = null;
+            if (org.apache.coyote.Constants.USE_CUSTOM_STATUS_MSG_IN_HEADER &&
+                    HttpMessages.isSafeInHttpHeader(response.getMessage())) {
+                message = response.getMessage();
+            }
+            if (message == null) {
+                write(HttpMessages.getInstance(
+                        response.getLocale()).getMessage(status));
+            } else {
+                write(message);
+            }
+        } else {
+            // The reason phrase is optional but the space before it is not. Skip
+            // sending the reason phrase. Clients should ignore it (RFC 7230) and it
+            // just wastes bytes.
+        }
 
         headerBuffer.put(Constants.CR).put(Constants.LF);
     }
@@ -474,6 +506,35 @@ public class Http11OutputBuffer implemen
     }
 
 
+    /**
+     * This method will write the contents of the specified String to the
+     * output stream, without filtering. This method is meant to be used to
+     * write the response header.
+     *
+     * @param s data to be written
+     */
+    private void write(String s) {
+        if (s == null) {
+            return;
+        }
+
+        // From the Tomcat 3.3 HTTP/1.0 connector
+        int len = s.length();
+        checkLengthBeforeWrite(len);
+        for (int i = 0; i < len; i++) {
+            char c = s.charAt (i);
+            // Note: This is clearly incorrect for many strings,
+            // but is the only consistent approach within the current
+            // servlet framework. It must suffice until servlet output
+            // streams properly encode their output.
+            if (((c <= 31) && (c != 9)) || c == 127 || c > 255) {
+                c = ' ';
+            }
+            headerBuffer.put((byte) c);
+        }
+    }
+
+
     /**
      * This method will write the specified integer to the output stream. This
      * method is meant to be used to write the response header.

Modified: tomcat/tc8.5.x/trunk/java/org/apache/coyote/http11/Http11Processor.java
URL: http://svn.apache.org/viewvc/tomcat/tc8.5.x/trunk/java/org/apache/coyote/http11/Http11Processor.java?rev=1788881&r1=1788880&r2=1788881&view=diff
==============================================================================
--- tomcat/tc8.5.x/trunk/java/org/apache/coyote/http11/Http11Processor.java (original)
+++ tomcat/tc8.5.x/trunk/java/org/apache/coyote/http11/Http11Processor.java Mon Mar 27 10:38:29 2017
@@ -226,7 +226,7 @@ public class Http11Processor extends Abs
 
     public Http11Processor(int maxHttpHeaderSize, AbstractEndpoint<?> endpoint,int maxTrailerSize,
             Set<String> allowedTrailerHeaders, int maxExtensionSize, int maxSwallowSize,
-            Map<String,UpgradeProtocol> httpUpgradeProtocols) {
+            Map<String,UpgradeProtocol> httpUpgradeProtocols, boolean sendReasonPhrase) {
 
         super(endpoint);
         userDataHelper = new UserDataHelper(log);
@@ -234,7 +234,7 @@ public class Http11Processor extends Abs
         inputBuffer = new Http11InputBuffer(request, maxHttpHeaderSize);
         request.setInputBuffer(inputBuffer);
 
-        outputBuffer = new Http11OutputBuffer(response, maxHttpHeaderSize);
+        outputBuffer = new Http11OutputBuffer(response, maxHttpHeaderSize, sendReasonPhrase);
         response.setOutputBuffer(outputBuffer);
 
         // Create and add the identity filters.

Added: tomcat/tc8.5.x/trunk/java/org/apache/tomcat/util/http/HttpMessages.java
URL: http://svn.apache.org/viewvc/tomcat/tc8.5.x/trunk/java/org/apache/tomcat/util/http/HttpMessages.java?rev=1788881&view=auto
==============================================================================
--- tomcat/tc8.5.x/trunk/java/org/apache/tomcat/util/http/HttpMessages.java (added)
+++ tomcat/tc8.5.x/trunk/java/org/apache/tomcat/util/http/HttpMessages.java Mon Mar 27 10:38:29 2017
@@ -0,0 +1,144 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+package org.apache.tomcat.util.http;
+
+import java.util.Locale;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+
+import org.apache.tomcat.util.res.StringManager;
+
+/**
+ * Handle (internationalized) HTTP messages.
+ *
+ * @author James Duncan Davidson [duncan@eng.sun.com]
+ * @author James Todd [gonzo@eng.sun.com]
+ * @author Jason Hunter [jch@eng.sun.com]
+ * @author Harish Prabandham
+ * @author costin@eng.sun.com
+ */
+public class HttpMessages {
+
+    private static final Map<Locale,HttpMessages> instances =
+            new ConcurrentHashMap<>();
+
+    private static final HttpMessages DEFAULT = new HttpMessages(
+            StringManager.getManager("org.apache.tomcat.util.http.res",
+                    Locale.getDefault()));
+
+
+    // XXX move message resources in this package
+    private final StringManager sm;
+
+    private String st_200 = null;
+    private String st_302 = null;
+    private String st_400 = null;
+    private String st_404 = null;
+
+    private HttpMessages(StringManager sm) {
+        this.sm = sm;
+    }
+
+
+    /**
+     * Get the status string associated with a status code. Common messages are
+     * cached.
+     *
+     * @param status The HTTP status code to retrieve the message for
+     *
+     * @return The HTTP status string that conforms to the requirements of the
+     *         HTTP specification
+     */
+    public String getMessage(int status) {
+        // method from Response.
+
+        // Does HTTP requires/allow international messages or
+        // are pre-defined? The user doesn't see them most of the time
+        switch( status ) {
+        case 200:
+            if(st_200 == null ) {
+                st_200 = sm.getString("sc.200");
+            }
+            return st_200;
+        case 302:
+            if(st_302 == null ) {
+                st_302 = sm.getString("sc.302");
+            }
+            return st_302;
+        case 400:
+            if(st_400 == null ) {
+                st_400 = sm.getString("sc.400");
+            }
+            return st_400;
+        case 404:
+            if(st_404 == null ) {
+                st_404 = sm.getString("sc.404");
+            }
+            return st_404;
+        }
+        return sm.getString("sc."+ status);
+    }
+
+
+    public static HttpMessages getInstance(Locale locale) {
+        HttpMessages result = instances.get(locale);
+        if (result == null) {
+            StringManager sm = StringManager.getManager(
+                    "org.apache.tomcat.util.http.res", locale);
+            if (Locale.getDefault().equals(sm.getLocale())) {
+                result = DEFAULT;
+            } else {
+                result = new HttpMessages(sm);
+            }
+            instances.put(locale, result);
+        }
+        return result;
+    }
+
+
+    /**
+     * Is the provided message safe to use in an HTTP header. Safe messages must
+     * meet the requirements of RFC2616 - i.e. must consist only of TEXT.
+     *
+     * @param msg   The message to test
+     * @return      <code>true</code> if the message is safe to use in an HTTP
+     *              header else <code>false</code>
+     */
+    public static boolean isSafeInHttpHeader(String msg) {
+        // Nulls are fine. It is up to the calling code to address any NPE
+        // concerns
+        if (msg == null) {
+            return true;
+        }
+
+        // Reason-Phrase is defined as *<TEXT, excluding CR, LF>
+        // TEXT is defined as any OCTET except CTLs, but including LWS
+        // OCTET is defined as an 8-bit sequence of data
+        // CTL is defined as octets 0-31 and 127
+        // LWS, if we exclude CR LF pairs, is defined as SP or HT (32, 9)
+        final int len = msg.length();
+        for (int i = 0; i < len; i++) {
+            char c = msg.charAt(i);
+            if (32 <= c && c <= 126 || 128 <= c && c <= 255 || c == 9) {
+                continue;
+            }
+            return false;
+        }
+
+        return true;
+    }
+}
\ No newline at end of file

Propchange: tomcat/tc8.5.x/trunk/java/org/apache/tomcat/util/http/HttpMessages.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: tomcat/tc8.5.x/trunk/java/org/apache/tomcat/util/http/res/LocalStrings.properties
URL: http://svn.apache.org/viewvc/tomcat/tc8.5.x/trunk/java/org/apache/tomcat/util/http/res/LocalStrings.properties?rev=1788881&view=auto
==============================================================================
--- tomcat/tc8.5.x/trunk/java/org/apache/tomcat/util/http/res/LocalStrings.properties (added)
+++ tomcat/tc8.5.x/trunk/java/org/apache/tomcat/util/http/res/LocalStrings.properties Mon Mar 27 10:38:29 2017
@@ -0,0 +1,78 @@
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements.  See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You under the Apache License, Version 2.0
+# (the "License"); you may not use this file except in compliance with
+# the License.  You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+# HttpMessages. The values in this file will be used in HTTP headers and as such
+# may only contain TEXT as defined by RFC 2616
+# All status codes registered with IANA can be found at
+# http://www.iana.org/assignments/http-status-codes/http-status-codes.xml
+# The list might be kept in sync with the one in
+# java/org/apache/catalina/valves/LocalStrings.properties
+sc.100=Continue
+sc.101=Switching Protocols
+sc.102=Processing
+sc.200=OK
+sc.201=Created
+sc.202=Accepted
+sc.203=Non-Authoritative Information
+sc.204=No Content
+sc.205=Reset Content
+sc.206=Partial Content
+sc.207=Multi-Status
+sc.208=Already Reported
+sc.226=IM Used
+sc.300=Multiple Choices
+sc.301=Moved Permanently
+sc.302=Found
+sc.303=See Other
+sc.304=Not Modified
+sc.305=Use Proxy
+sc.307=Temporary Redirect
+sc.308=Permanent Redirect
+sc.400=Bad Request
+sc.401=Unauthorized
+sc.402=Payment Required
+sc.403=Forbidden
+sc.404=Not Found
+sc.405=Method Not Allowed
+sc.406=Not Acceptable
+sc.407=Proxy Authentication Required
+sc.408=Request Timeout
+sc.409=Conflict
+sc.410=Gone
+sc.411=Length Required
+sc.412=Precondition Failed
+sc.413=Request Entity Too Large
+sc.414=Request-URI Too Long
+sc.415=Unsupported Media Type
+sc.416=Requested Range Not Satisfiable
+sc.417=Expectation Failed
+sc.422=Unprocessable Entity
+sc.423=Locked
+sc.424=Failed Dependency
+sc.426=Upgrade Required
+sc.428=Precondition Required
+sc.429=Too Many Requests
+sc.431=Request Header Fields Too Large
+sc.500=Internal Server Error
+sc.501=Not Implemented
+sc.502=Bad Gateway
+sc.503=Service Unavailable
+sc.504=Gateway Timeout
+sc.505=HTTP Version Not Supported
+sc.506=Variant Also Negotiates (Experimental)
+sc.507=Insufficient Storage
+sc.508=Loop Detected
+sc.510=Not Extended
+sc.511=Network Authentication Required
\ No newline at end of file

Propchange: tomcat/tc8.5.x/trunk/java/org/apache/tomcat/util/http/res/LocalStrings.properties
------------------------------------------------------------------------------
    svn:eol-style = native

Added: tomcat/tc8.5.x/trunk/java/org/apache/tomcat/util/http/res/LocalStrings_es.properties
URL: http://svn.apache.org/viewvc/tomcat/tc8.5.x/trunk/java/org/apache/tomcat/util/http/res/LocalStrings_es.properties?rev=1788881&view=auto
==============================================================================
--- tomcat/tc8.5.x/trunk/java/org/apache/tomcat/util/http/res/LocalStrings_es.properties (added)
+++ tomcat/tc8.5.x/trunk/java/org/apache/tomcat/util/http/res/LocalStrings_es.properties Mon Mar 27 10:38:29 2017
@@ -0,0 +1,61 @@
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements.  See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You under the Apache License, Version 2.0
+# (the "License"); you may not use this file except in compliance with
+# the License.  You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+# HttpMessages. The values in this file will be used in HTTP headers and as such
+# may only contain TEXT as defined by RFC 2616
+sc.100 = Continuar
+sc.101 = Cambiando Protocolos
+sc.200 = OK
+sc.201 = Creado
+sc.202 = Aceptado
+sc.203 = Informaci\u00F3n No-Autorizativa
+sc.204 = Sin Contenido
+sc.205 = Reponer Contenido
+sc.206 = Contenido Parcial
+sc.207 = Multi-Estado
+sc.300 = M\u00FAltiples Elecciones
+sc.301 = Movido permanentemente
+sc.302 = Movido temporalmente
+sc.303 = Mirar Otro
+sc.304 = No Modificado
+sc.305 = Usar Proxy
+sc.307 = Redirecci\u00F3n Temporal
+sc.400 = Petici\u00F3n incorrecta
+sc.401 = No Autorizado
+sc.402 = Pago requerido
+sc.403 = Prohibido
+sc.404 = No Encontrado
+sc.405 = M\u00E9todo No Permitido
+sc.406 = No Aceptable
+sc.407 = Autentificaci\u00F3n Proxy Requerida
+sc.408 = Request Caducada
+sc.409 = Conflicto
+sc.410 = Ido
+sc.411 = Longitud Requerida
+sc.412 = Precondici\u00F3n Fallada
+sc.413 = Entidad de Request Demasiado Grande
+sc.414 = Request-URI Demasiado Larga
+sc.415 = Tipo de Medio No Soportado
+sc.416 = El Rango Pedido No Ser Satisfecho
+sc.417 = Expectativa Fallada
+sc.422 = Entidad Improcesable
+sc.423 = Bloqueado
+sc.424 = Dependencia Fallida
+sc.500 = Error Interno del Servidor
+sc.501 = No Implementado
+sc.502 = Pasarela Incorrecta
+sc.503 = Servicio no Disponible
+sc.504 = Pasarela Caducada
+sc.505 = Versi\u00F3n de HTTP No Soportada
+sc.507 = Almacenaje Insuficiente
\ No newline at end of file

Propchange: tomcat/tc8.5.x/trunk/java/org/apache/tomcat/util/http/res/LocalStrings_es.properties
------------------------------------------------------------------------------
    svn:eol-style = native

Added: tomcat/tc8.5.x/trunk/java/org/apache/tomcat/util/http/res/LocalStrings_fr.properties
URL: http://svn.apache.org/viewvc/tomcat/tc8.5.x/trunk/java/org/apache/tomcat/util/http/res/LocalStrings_fr.properties?rev=1788881&view=auto
==============================================================================
--- tomcat/tc8.5.x/trunk/java/org/apache/tomcat/util/http/res/LocalStrings_fr.properties (added)
+++ tomcat/tc8.5.x/trunk/java/org/apache/tomcat/util/http/res/LocalStrings_fr.properties Mon Mar 27 10:38:29 2017
@@ -0,0 +1,61 @@
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements.  See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You under the Apache License, Version 2.0
+# (the "License"); you may not use this file except in compliance with
+# the License.  You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+# HttpMessages. The values in this file will be used in HTTP headers and as such
+# may only contain TEXT as defined by RFC 2616
+sc.100=Continuer
+sc.101=Changement de Protocols
+sc.200=OK
+sc.201=Cr\u00e9e
+sc.202=Accept\u00e9
+sc.203=Information Sans-Autorit\u00e9
+sc.204=Pas de Contenu
+sc.205=Remise \u00e0 Z\u00e9ro de Contenu
+sc.206=Contenu Partiel
+sc.207=Etat Multiple
+sc.300=Choix Multiples
+sc.301=D\u00e9plac\u00e9 de fa\u00e7on Permanente
+sc.302=D\u00e9plac\u00e9 Temporairement
+sc.303=Voir Autre
+sc.304=Non Modifi\u00e9
+sc.305=Utilisation de Relais
+sc.307=Redirection Temporaire
+sc.400=Mauvaise Requ\u00eate
+sc.401=Non-Autoris\u00e9
+sc.402=Paiement N\u00e9cessaire
+sc.403=Interdit
+sc.404=Introuvable
+sc.405=M\u00e9thode Non Autoris\u00e9e
+sc.406=Inacceptable
+sc.407=Authentification de Relais N\u00e9cessaire
+sc.408=D\u00e9passement de D\u00e9lais pour la Requ\u00eate
+sc.409=Conflit
+sc.410=Parti
+sc.411=Taille Demand\u00e9e
+sc.412=Echec de Pr\u00e9-condition
+sc.413=Entit\u00e9 de Requ\u00eate Trop Grande
+sc.414=URI de Requ\u00eate Trop Grande
+sc.415=Type de Support Non Support\u00e9
+sc.416=Etendue de Requ\u00eate Irr\u00e9alisable
+sc.417=Echec d'Attente
+sc.422=Entit\u00e9 Ing\u00e9rable
+sc.424=Echec de D\u00e9pendance
+sc.500=Erreur Interne de Servlet
+sc.501=Non Impl\u00e9ment\u00e9
+sc.502=Mauvaise Passerelle
+sc.503=Service Indisponible
+sc.504=D\u00e9passement de D\u00e9lais pour la Passerelle
+sc.505=Version HTTP Non Support\u00e9e
+sc.507=Stockage Insuffisant
\ No newline at end of file

Propchange: tomcat/tc8.5.x/trunk/java/org/apache/tomcat/util/http/res/LocalStrings_fr.properties
------------------------------------------------------------------------------
    svn:eol-style = native

Modified: tomcat/tc8.5.x/trunk/test/org/apache/coyote/http11/filters/TesterOutputBuffer.java
URL: http://svn.apache.org/viewvc/tomcat/tc8.5.x/trunk/test/org/apache/coyote/http11/filters/TesterOutputBuffer.java?rev=1788881&r1=1788880&r2=1788881&view=diff
==============================================================================
--- tomcat/tc8.5.x/trunk/test/org/apache/coyote/http11/filters/TesterOutputBuffer.java (original)
+++ tomcat/tc8.5.x/trunk/test/org/apache/coyote/http11/filters/TesterOutputBuffer.java Mon Mar 27 10:38:29 2017
@@ -38,7 +38,7 @@ public class TesterOutputBuffer extends
 
 
     public TesterOutputBuffer(Response response, int headerBufferSize) {
-        super(response, headerBufferSize);
+        super(response, headerBufferSize, false);
         outputStreamOutputBuffer = new OutputStreamOutputBuffer();
     }
 

Modified: tomcat/tc8.5.x/trunk/test/org/apache/tomcat/util/buf/TestByteChunk.java
URL: http://svn.apache.org/viewvc/tomcat/tc8.5.x/trunk/test/org/apache/tomcat/util/buf/TestByteChunk.java?rev=1788881&r1=1788880&r2=1788881&view=diff
==============================================================================
--- tomcat/tc8.5.x/trunk/test/org/apache/tomcat/util/buf/TestByteChunk.java (original)
+++ tomcat/tc8.5.x/trunk/test/org/apache/tomcat/util/buf/TestByteChunk.java Mon Mar 27 10:38:29 2017
@@ -32,7 +32,7 @@ public class TestByteChunk {
 
     @Test
     public void testConvertToBytes() throws UnsupportedEncodingException {
-        String string = "HTTP/1.1 100 Continue\r\n";
+        String string = "HTTP/1.1 100 \r\n\r\n";
         byte[] bytes = ByteChunk.convertToBytes(string);
         byte[] expected = string.getBytes("ISO-8859-1");
         assertTrue(Arrays.equals(bytes, expected));

Modified: tomcat/tc8.5.x/trunk/webapps/docs/changelog.xml
URL: http://svn.apache.org/viewvc/tomcat/tc8.5.x/trunk/webapps/docs/changelog.xml?rev=1788881&r1=1788880&r2=1788881&view=diff
==============================================================================
--- tomcat/tc8.5.x/trunk/webapps/docs/changelog.xml (original)
+++ tomcat/tc8.5.x/trunk/webapps/docs/changelog.xml Mon Mar 27 10:38:29 2017
@@ -84,6 +84,13 @@
   </subsection>
   <subsection name="Coyote">
     <changelog>
+      <add>
+        <bug>60362</bug>: Add a new Connector configuration
+        <code>sendReasonPhrase</code>. When this attribute is set to
+        <code>true</code>, a reason phrase will be sent with the response.
+        By default a reason phrase will not be sent. This option is deprecated
+        and is not available in Tomcat 9. (violetagg)
+      </add>
       <fix>
         Fix HTTP/2 incorrect input unblocking on EOF. (remm)
       </fix>

Modified: tomcat/tc8.5.x/trunk/webapps/docs/config/ajp.xml
URL: http://svn.apache.org/viewvc/tomcat/tc8.5.x/trunk/webapps/docs/config/ajp.xml?rev=1788881&r1=1788880&r2=1788881&view=diff
==============================================================================
--- tomcat/tc8.5.x/trunk/webapps/docs/config/ajp.xml (original)
+++ tomcat/tc8.5.x/trunk/webapps/docs/config/ajp.xml Mon Mar 27 10:38:29 2017
@@ -236,6 +236,14 @@
       The default value is <code>false</code>.</p>
     </attribute>
 
+    <attribute name="sendReasonPhrase" required="false">
+      <p>Set this attribute to <code>true</code> if you wish to have
+      a reason phrase in the response.
+      The default value is <code>false</code>.</p>
+      <p><strong>Note:</strong> This option is deprecated and will be removed
+      in Tomcat 9. The reason phrase will not be sent.</p>
+    </attribute>
+
     <attribute name="URIEncoding" required="false">
       <p>This specifies the character encoding used to decode the URI bytes,
       after %xx decoding the URL. If not specified, UTF-8 will be used unless

Modified: tomcat/tc8.5.x/trunk/webapps/docs/config/http.xml
URL: http://svn.apache.org/viewvc/tomcat/tc8.5.x/trunk/webapps/docs/config/http.xml?rev=1788881&r1=1788880&r2=1788881&view=diff
==============================================================================
--- tomcat/tc8.5.x/trunk/webapps/docs/config/http.xml (original)
+++ tomcat/tc8.5.x/trunk/webapps/docs/config/http.xml Mon Mar 27 10:38:29 2017
@@ -236,6 +236,14 @@
       The default value is <code>false</code>.</p>
     </attribute>
 
+    <attribute name="sendReasonPhrase" required="false">
+      <p>Set this attribute to <code>true</code> if you wish to have
+      a reason phrase in the response.
+      The default value is <code>false</code>.</p>
+      <p><strong>Note:</strong> This option is deprecated and will be removed
+      in Tomcat 9. The reason phrase will not be sent.</p>
+    </attribute>
+
     <attribute name="URIEncoding" required="false">
       <p>This specifies the character encoding used to decode the URI bytes,
       after %xx decoding the URL. If not specified, UTF-8 will be used unless

Modified: tomcat/tc8.5.x/trunk/webapps/docs/config/systemprops.xml
URL: http://svn.apache.org/viewvc/tomcat/tc8.5.x/trunk/webapps/docs/config/systemprops.xml?rev=1788881&r1=1788880&r2=1788881&view=diff
==============================================================================
--- tomcat/tc8.5.x/trunk/webapps/docs/config/systemprops.xml (original)
+++ tomcat/tc8.5.x/trunk/webapps/docs/config/systemprops.xml Mon Mar 27 10:38:29 2017
@@ -553,6 +553,17 @@
 
   <properties>
 
+    <property
+    name="org.apache.coyote. USE_CUSTOM_STATUS_MSG_IN_HEADER"><p>If this is
+      <code>true</code>, custom HTTP status messages will be used within HTTP
+      headers. If a custom message is specified that is not valid for use in an
+      HTTP header (as defined by RFC2616) then the custom message will be
+      ignored and the default message used.</p>
+      <p>If not specified, the default value of <code>false</code> will be used.</p>
+      <p><strong>Note:</strong> This option is deprecated and will be removed
+      in Tomcat 9. The reason phrase will not be sent.</p>
+    </property>
+
     <property name="catalina.useNaming">
       <p>If this is <code>false</code> it will override the
       <code>useNaming</code> attribute for all <a href="context.html">



---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@tomcat.apache.org
For additional commands, e-mail: dev-help@tomcat.apache.org