https://issues.apache.org/bugzilla/show_bug.cgi?id=54734
            Bug ID: 54734
           Summary: Tomcat Servlet 3.1 API needs to be synchronized with
                    Proposed Final Draft
           Product: Tomcat 8
           Version: trunk
          Hardware: All
                OS: All
            Status: NEW
          Severity: major
          Priority: P2
         Component: Specification APIs
          Assignee: dev@tomcat.apache.org
          Reporter: nicho...@nicholaswilliams.net
    Classification: Unclassified

Created attachment 30084
  --> https://issues.apache.org/bugzilla/attachment.cgi?id=30084&action=edit
Patch to bring Tomcat in line with latest Servlet 3.1 spec

Tomcat's javax.servlet.http.WebConnection interface should extend
AutoCloseable, but it does not.

In Tomcat's javax.servlet.ReadListener interface, onDataAvailable() and
onAllDataRead() should throw IOException, but they do not.

In Tomcat's javax.servlet.WriteListener interface, onWritePossible() should
throw IOException, but it does not.

Tomcat's javax.servlet.ServletContext class is missing the following method:
  public String getVirtualServerName();

Patch attached for the above issues.

Tomcat's javax.servlet.http.NoBodyResponse implementation is interesting.
First, it Servlet 2.5 the void setContentLength() method was as follows:

void setContentLength();
  Code:
     0: aload_0       
     1: getfield      #6                  // Field didSetContentLength:Z
     4: ifne          23
     7: aload_0       
     8: getfield      #2                  // Field
resp:Ljavax/servlet/http/HttpServletResponse;
    11: aload_0       
    12: getfield      #5                  // Field
noBody:Ljavax/servlet/http/NoBodyOutputStream;
    15: invokevirtual #7                  // Method
javax/servlet/http/NoBodyOutputStream.getContentLength:()I
    18: invokeinterface #8,  2            // InterfaceMethod
javax/servlet/http/HttpServletResponse.setContentLength:(I)V
    23: return 


Which is equivalent to:

    void setContentLength() {
        if (!didSetContentLength)
          resp.setContentLength(noBody.getContentLength());
    }

It changed in Servlet 3.0 (and remained the same in Servlet 3.1) and is now:

  void setContentLength();
    Code:
       0: aload_0       
       1: getfield      #5                  // Field didSetContentLength:Z
       4: ifne          32
       7: aload_0       
       8: getfield      #6                  // Field
writer:Ljava/io/PrintWriter;
      11: ifnull        21
      14: aload_0       
      15: getfield      #6                  // Field
writer:Ljava/io/PrintWriter;
      18: invokevirtual #7                  // Method
java/io/PrintWriter.flush:()V
      21: aload_0       
      22: aload_0       
      23: getfield      #4                  // Field
noBody:Ljavax/servlet/http/NoBodyOutputStream;
      26: invokevirtual #8                  // Method
javax/servlet/http/NoBodyOutputStream.getContentLength:()I
      29: invokevirtual #9                  // Method setContentLength:(I)V
      32: return

This is roughly equivalent to:

    void setContentLength() {
        if (!didSetContentLength) {
            if (writer != null)
                writer.flush();
            super.setContentLength(noBody.getContentLength());
        }
    }

However, Tomcat's implementation is still:

    void setContentLength() {
        if (!didSetContentLength)
          super.setContentLength(noBody.getContentLength());
    }

The spec implementation is correct, and the Tomcat implementation could report
incorrect content length if the writer has not been flushed. I will attach a
separate patch in the following comment that fixes this.

Finally, I noticed that Tomcat's javax.servlet.http.NoBodyResponse class has
the following methods that are not in the spec:

  public void setContentLengthLong(long);
  public void setHeader(String, String);
  public void addHeader(String, String);
  public void setIntHeader(String, int);
  public void addIntHeader(String, int);

However, I do not believe this is a problem in Tomcat. The last four were added
as part of https://issues.apache.org/bugzilla/show_bug.cgi?id=53454 and the
setContentLengthLong() was added by Mark to correspond with that new method in
Servlet 3.1. I believe this is a problem with the Oracle implementation, and
these methods should be in that. Tomcat's implementation clearly adheres to the
spirit of the spec. The spec JAR does not. I'm going to file an issue about
this in the servlet spec JIRA.

-- 
You are receiving this mail because:
You are the assignee for the bug.

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

Reply via email to