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: [email protected]
Reporter: [email protected]
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: [email protected]
For additional commands, e-mail: [email protected]