Fix bug in request handling when incoming requests are attached to an existing response and the response is generated by directly accessing the res.servletResponse HttpServletResponse instance.
This commit is contained in:
parent
a635964fc8
commit
33fac6be68
3 changed files with 31 additions and 19 deletions
|
@ -493,11 +493,11 @@ public final class ResponseTrans extends Writer implements Serializable {
|
|||
|
||||
/**
|
||||
* Allow to directly set the byte array for the response. Calling this more than once will
|
||||
* overwrite the previous output. We take a generic object as parameter to be able to
|
||||
* generate a better error message, but it must be byte[].
|
||||
* overwrite the previous output.
|
||||
* @param bytes an arbitrary byte array
|
||||
*/
|
||||
public void writeBinary(byte[] what) {
|
||||
response = what;
|
||||
public void writeBinary(byte[] bytes) {
|
||||
response = bytes;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -649,6 +649,11 @@ public final class ResponseTrans extends Writer implements Serializable {
|
|||
// there's no point in closing the response buffer
|
||||
HttpServletResponse res = reqtrans.getServletResponse();
|
||||
if (res != null && res.isCommitted()) {
|
||||
// response was committed using HttpServletResponse directly. We need
|
||||
// set response to null and notify waiters in order to let attached
|
||||
// requests know they can't reuse this response.
|
||||
response = null;
|
||||
notifyAll();
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -664,7 +669,8 @@ public final class ResponseTrans extends Writer implements Serializable {
|
|||
|
||||
boolean encodingError = false;
|
||||
|
||||
// only close if the response hasn't been closed yet
|
||||
// only close if the response hasn't been closed yet, and if no
|
||||
// response was generated using writeBinary().
|
||||
if (response == null) {
|
||||
// if debug buffer exists, append it to main buffer
|
||||
if (contentType != null &&
|
||||
|
@ -747,7 +753,7 @@ public final class ResponseTrans extends Writer implements Serializable {
|
|||
* @return the response body
|
||||
*/
|
||||
public byte[] getContent() {
|
||||
return (response == null) ? new byte[0] : response;
|
||||
return response;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -720,6 +720,14 @@ public final class Application implements Runnable {
|
|||
|
||||
if (ev != null) {
|
||||
res = ev.attachHttpRequest(req);
|
||||
if (res != null) {
|
||||
// we can only use the existing response object if the response
|
||||
// wasn't written to the HttpServletResponse directly.
|
||||
res.waitForClose();
|
||||
if (res.getContent() == null) {
|
||||
res = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (res == null) {
|
||||
|
@ -752,8 +760,6 @@ public final class Application implements Runnable {
|
|||
} catch (UnsupportedEncodingException uee) {
|
||||
logError("Unsupported response encoding", uee);
|
||||
}
|
||||
} else {
|
||||
res.waitForClose();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -345,17 +345,17 @@ public abstract class AbstractServletClient extends HttpServlet {
|
|||
res.setContentLength(hopres.getContentLength());
|
||||
res.setContentType(hopres.getContentType());
|
||||
|
||||
if ("HEAD".equalsIgnoreCase(req.getMethod())) {
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
OutputStream out = res.getOutputStream();
|
||||
|
||||
out.write(hopres.getContent());
|
||||
out.flush();
|
||||
} catch (Exception iox) {
|
||||
log("Exception in writeResponse: " + iox);
|
||||
if (!"HEAD".equalsIgnoreCase(req.getMethod())) {
|
||||
byte[] content = hopres.getContent();
|
||||
if (content != null) {
|
||||
try {
|
||||
OutputStream out = res.getOutputStream();
|
||||
out.write(content);
|
||||
out.flush();
|
||||
} catch (Exception iox) {
|
||||
log("Exception in writeResponse: " + iox);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue