RFR: 8349670: HttpServer: sending interim responses fails after JDK-7026262 [v3]

Michael McMahon michaelm at openjdk.org
Tue Sep 23 16:11:42 UTC 2025


On Tue, 23 Sep 2025 14:50:23 GMT, Josiah Noel <duke at openjdk.org> wrote:

>> Following the guideline of the last comment on [JDK-8349670](https://bugs.openjdk.org/browse/JDK-8349670?focusedId=14794649&page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel#comment-14794649), resolves the issue where sending a 1xx status code would close the input stream, preventing the server from reading the body. 
>> 
>> - When a 1xx status code is sent by `sendResponseHeaders`, the input/output streams will not be closed prematurely.
>> - sentHeaders will not be set to true when sending 1xx status codes
>
> Josiah Noel has updated the pull request incrementally with one additional commit since the last revision:
> 
>   remove upgrade

I agree that switching protocols should not be part of the PR.

We discussed this before, but I think we _should_ include as part of this fix, some symbolic constants to represent the special (and counter-intuitive) length values of 0 and -1 for sendResponseHeaders. I started a patch for this and can provide what I had. The idea is to define two constants in HttpExchange

        /**
         * No response body is being sent with this response
         */
        public static final long RSPBODY_EMPTY = -1l;
   
        /**
         * The response body is unspecified and will be chunk encoded
         */
        public static final long RSPBODY_CHUNKED = 0;

and then link to these constants (instead of stating 0, or -1 literally) in the apidoc for sendResponseHeaders. The following could be a starting point for this:

      /**
-      * Starts sending the response back to the client using the current set of
-      * response headers and the numeric response code as specified in this
+      * Starts sending the final response back to the client using the current set of
+      * response headers obtained from {@link #getResponseHeaders()} and the numeric 
+      * response code as specified in this
       * method. The response body length is also specified as follows. If the
       * response length parameter is greater than {@code zero}, this specifies an
       * exact number of bytes to send and the application must send that exact
-      * amount of data. If the response length parameter is {@code zero}, then
-      * chunked transfer encoding is used and an arbitrary amount of data may be
+      * amount of data. If the response length parameter has the value 
+      * {@link #RSPBODY_CHUNKED} then the response body uses
+      * chunked transfer encoding and an arbitrary amount of data may be
       * sent. The application terminates the response body by closing the
       * {@link OutputStream}.
-      * If response length has the value {@code -1} then no response body is
-      * being sent.
+      * If response length has the value {@link #RSPBODY_EMPTY} then no 
+      * response body is being sent.
       *
       * <p> If the content-length response header has not already been set then
       * this is set to the appropriate value depending on the response length
       * parameter.
       *
       * <p> This method must be called prior to calling {@link #getResponseBody()}.
       *
+      * <p> The request body must be consumed before calling this method.
+      *
       * @implNote This implementation allows the caller to instruct the
       * server to force a connection close after the exchange terminates, by
       * supplying a {@code Connection: close} header to the {@linkplain
       * #getResponseHeaders() response headers} before {@code sendResponseHeaders}
       * is called.
       *
       * @param rCode          the response code to send
       * @param responseLength if {@literal > 0}, specifies a fixed response body
       *                       length and that exact number of bytes must be written
       *                       to the stream acquired from {@link #getResponseCode()}
-      *                       If {@literal == 0}, then chunked encoding is used,
+      *                       If equal to {@link #RSPBODY_CHUNKED}, then chunked encoding is used,
       *                       and an arbitrary number of bytes may be written.
-      *                       If {@literal <= -1}, then no response body length is
+      *                       If equal to {@link #RSPBODY_EMPTY}, then no response body length is
       *                       specified and no response body may be written.
       * @throws IOException   if the response headers have already been sent or an I/O error occurs
       * @see   HttpExchange#getResponseBody()
       */
      public abstract void sendResponseHeaders(int rCode, long responseLength) throws IOException;

It's only a doc change obviously. So, existing (correct) code can continue to use numeric values, but hopefully new code can be less error-prone if the constant names are used.

-------------

PR Comment: https://git.openjdk.org/jdk/pull/27069#issuecomment-3324672414


More information about the net-dev mailing list