Skip to content

Commit 9140ad7

Browse files
committed
fix: response body write failed when getOutputStream already called
1 parent 8676efa commit 9140ad7

File tree

11 files changed

+403
-89
lines changed

11 files changed

+403
-89
lines changed

generator/src/main/java/com/reajason/javaweb/probe/payload/response/ApusicWriter.java

Lines changed: 34 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
11
package com.reajason.javaweb.probe.payload.response;
22

3+
import java.io.ByteArrayOutputStream;
4+
import java.io.OutputStream;
5+
import java.io.PrintStream;
36
import java.io.PrintWriter;
47
import java.lang.reflect.Array;
58
import java.lang.reflect.Field;
@@ -32,15 +35,25 @@ public ApusicWriter() {
3235
Object response = getFieldValue(servletInvocation, "response");
3336
String data = getDataFromReq(request);
3437
if (data != null && !data.isEmpty()) {
35-
PrintWriter writer = (PrintWriter) invokeMethod(response, "getWriter", null, null);
38+
String result = "";
3639
try {
37-
writer.write(run(data));
40+
result = run(data);
3841
} catch (Throwable e) {
39-
e.printStackTrace();
40-
e.printStackTrace(writer);
42+
result = getErrorMessage(e);
43+
}
44+
if (result != null) {
45+
try {
46+
OutputStream outputStream = (OutputStream) invokeMethod(response, "getOutputStream", null, null);
47+
outputStream.write(result.getBytes());
48+
outputStream.flush();
49+
outputStream.close();
50+
} catch (Throwable e) {
51+
PrintWriter writer = (PrintWriter) invokeMethod(response, "getWriter", null, null);
52+
writer.write(result);
53+
writer.flush();
54+
writer.close();
55+
}
4156
}
42-
writer.flush();
43-
writer.close();
4457
return;
4558
}
4659
}
@@ -96,4 +109,19 @@ public static Object getFieldValue(Object obj, String name) throws Exception {
96109
}
97110
throw new NoSuchFieldException(obj.getClass().getName() + " Field not found: " + name);
98111
}
112+
113+
@SuppressWarnings("all")
114+
private String getErrorMessage(Throwable throwable) {
115+
PrintStream printStream = null;
116+
try {
117+
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
118+
printStream = new PrintStream(outputStream);
119+
throwable.printStackTrace(printStream);
120+
return outputStream.toString();
121+
} finally {
122+
if (printStream != null) {
123+
printStream.close();
124+
}
125+
}
126+
}
99127
}

generator/src/main/java/com/reajason/javaweb/probe/payload/response/GlassFishWriter.java

Lines changed: 46 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
11
package com.reajason.javaweb.probe.payload.response;
22

3+
import java.io.ByteArrayOutputStream;
4+
import java.io.OutputStream;
5+
import java.io.PrintStream;
36
import java.io.PrintWriter;
47
import java.lang.reflect.Field;
58
import java.lang.reflect.Method;
@@ -22,10 +25,8 @@ public GlassFishWriter() {
2225
// GlassFish3
2326
Thread thread = Thread.currentThread();
2427
Object request = invokeMethod(getFieldValue(getFieldValue(thread, "processorTask"), "request"), "getNote", new Class[]{Integer.TYPE}, new Object[]{1});
25-
Object response = invokeMethod(request, "getResponse", null, null);
26-
String data = getDataFromReq(request);
27-
if (data != null && !data.isEmpty()) {
28-
execute(response, data);
28+
if (tryWriteRes(request)) {
29+
return;
2930
}
3031
} catch (Exception x) {
3132
// GlassFish4+
@@ -48,10 +49,7 @@ public GlassFishWriter() {
4849
}
4950
Object notesHolder = getFieldValue(getFieldValue(coyoteRequest, "request"), "notesHolder");
5051
Object request = invokeMethod(notesHolder, "getAttribute", new Class[]{String.class}, new Object[]{"org.apache.catalina.connector.Request"});
51-
Object response = invokeMethod(request, "getResponse", null, null);
52-
String data = getDataFromReq(request);
53-
if (data != null && !data.isEmpty()) {
54-
execute(response, data);
52+
if (tryWriteRes(request)) {
5553
return;
5654
}
5755
}
@@ -64,15 +62,32 @@ public GlassFishWriter() {
6462
}
6563
}
6664

67-
private void execute(Object response, String data) throws Exception {
68-
PrintWriter writer = (PrintWriter) invokeMethod(response, "getWriter", null, null);
69-
try {
70-
writer.write(run(data));
71-
} catch (Throwable e) {
72-
e.printStackTrace(writer);
65+
private boolean tryWriteRes(Object request) throws Exception {
66+
Object response = invokeMethod(request, "getResponse", null, null);
67+
String data = getDataFromReq(request);
68+
if (data != null && !data.isEmpty()) {
69+
String result = "";
70+
try {
71+
result = run(data);
72+
} catch (Throwable e) {
73+
result = getErrorMessage(e);
74+
}
75+
if (result != null) {
76+
try {
77+
OutputStream outputStream = (OutputStream) invokeMethod(response, "getOutputStream", null, null);
78+
outputStream.write(result.getBytes());
79+
outputStream.flush();
80+
outputStream.close();
81+
} catch (Throwable e) {
82+
PrintWriter writer = (PrintWriter) invokeMethod(response, "getWriter", null, null);
83+
writer.write(result);
84+
writer.flush();
85+
writer.close();
86+
}
87+
}
88+
return true;
7389
}
74-
writer.flush();
75-
writer.close();
90+
return false;
7691
}
7792

7893
private String getDataFromReq(Object request) throws Exception {
@@ -119,4 +134,19 @@ public static Object getFieldValue(Object obj, String name) throws Exception {
119134
}
120135
throw new NoSuchFieldException(obj.getClass().getName() + " Field not found: " + name);
121136
}
137+
138+
@SuppressWarnings("all")
139+
private String getErrorMessage(Throwable throwable) {
140+
PrintStream printStream = null;
141+
try {
142+
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
143+
printStream = new PrintStream(outputStream);
144+
throwable.printStackTrace(printStream);
145+
return outputStream.toString();
146+
} finally {
147+
if (printStream != null) {
148+
printStream.close();
149+
}
150+
}
151+
}
122152
}

generator/src/main/java/com/reajason/javaweb/probe/payload/response/JettyWriter.java

Lines changed: 39 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,10 @@
22

33
import org.eclipse.jetty.util.Callback;
44

5+
import java.io.ByteArrayOutputStream;
6+
import java.io.OutputStream;
7+
import java.io.PrintStream;
58
import java.io.PrintWriter;
6-
import java.io.StringWriter;
79
import java.lang.reflect.Array;
810
import java.lang.reflect.Field;
911
import java.lang.reflect.Method;
@@ -49,23 +51,30 @@ public JettyWriter() {
4951
}
5052
String data = getDataFromReq(request);
5153
if (data != null && !data.isEmpty()) {
52-
StringWriter sw = new StringWriter();
53-
PrintWriter writer = new PrintWriter(sw);
54+
String result = "";
5455
try {
55-
writer.write(run(data));
56+
result = run(data);
5657
} catch (Throwable e) {
57-
e.printStackTrace();
58-
e.printStackTrace(writer);
58+
result = getErrorMessage(e);
5959
}
60-
String result = sw.toString();
61-
System.out.println("result: " + result);
62-
try {
63-
PrintWriter resWriter = (PrintWriter) invokeMethod(response, "getWriter", null, null);
64-
resWriter.write(result);
65-
} catch (Exception e) {
66-
invokeMethod(response, "setStatus", new Class[]{int.class}, new Object[]{200});
67-
ByteBuffer content = UTF_8.encode(result);
68-
invokeMethod(response, "write", new Class[]{boolean.class, ByteBuffer.class, Callback.class}, new Object[]{true, content, null});
60+
if (result != null) {
61+
try {
62+
OutputStream outputStream = (OutputStream) invokeMethod(response, "getOutputStream", null, null);
63+
outputStream.write(result.getBytes());
64+
outputStream.flush();
65+
outputStream.close();
66+
} catch (Throwable e) {
67+
try {
68+
PrintWriter resWriter = (PrintWriter) invokeMethod(response, "getWriter", null, null);
69+
resWriter.write(result);
70+
resWriter.flush();
71+
resWriter.close();
72+
} catch (Exception x) {
73+
invokeMethod(response, "setStatus", new Class[]{int.class}, new Object[]{200});
74+
ByteBuffer content = UTF_8.encode(result);
75+
invokeMethod(response, "write", new Class[]{boolean.class, ByteBuffer.class, Callback.class}, new Object[]{true, content, null});
76+
}
77+
}
6978
}
7079
return;
7180
}
@@ -122,4 +131,19 @@ public static Object getFieldValue(Object obj, String name) throws Exception {
122131
}
123132
throw new NoSuchFieldException(obj.getClass().getName() + " Field not found: " + name);
124133
}
134+
135+
@SuppressWarnings("all")
136+
private String getErrorMessage(Throwable throwable) {
137+
PrintStream printStream = null;
138+
try {
139+
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
140+
printStream = new PrintStream(outputStream);
141+
throwable.printStackTrace(printStream);
142+
return outputStream.toString();
143+
} finally {
144+
if (printStream != null) {
145+
printStream.close();
146+
}
147+
}
148+
}
125149
}

generator/src/main/java/com/reajason/javaweb/probe/payload/response/ResinWriter.java

Lines changed: 41 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
11
package com.reajason.javaweb.probe.payload.response;
22

3+
import java.io.ByteArrayOutputStream;
4+
import java.io.OutputStream;
5+
import java.io.PrintStream;
36
import java.io.PrintWriter;
47
import java.lang.reflect.Field;
58
import java.lang.reflect.Method;
@@ -22,17 +25,30 @@ public ResinWriter() {
2225
Object request = invokeMethod(invocationClazz, "getContextRequest", null, null);
2326
Object response = getFieldValue(request, "_response");
2427
String data = getDataFromReq(request);
25-
PrintWriter writer = (PrintWriter) invokeMethod(response, "getWriter", null, null);
26-
try {
27-
writer.write(run(data));
28-
} catch (Throwable e) {
29-
e.printStackTrace(writer);
28+
if (data != null && !data.isEmpty()) {
29+
String result = "";
30+
try {
31+
result = run(data);
32+
} catch (Throwable e) {
33+
result = getErrorMessage(e);
34+
}
35+
if (result != null) {
36+
try {
37+
OutputStream outputStream = (OutputStream) invokeMethod(response, "getOutputStream", null, null);
38+
outputStream.write(result.getBytes());
39+
outputStream.flush();
40+
outputStream.close();
41+
} catch (Throwable e) {
42+
PrintWriter writer = (PrintWriter) invokeMethod(response, "getWriter", null, null);
43+
writer.write(result);
44+
writer.flush();
45+
writer.close();
46+
}
47+
}
48+
// com.caucho.server.connection.AbstractHttpResponse.close
49+
// 不关闭 response 的话会遇到重复写响应体的情况
50+
// invokeMethod(response, "close", null, null);
3051
}
31-
writer.flush();
32-
writer.close();
33-
// com.caucho.server.connection.AbstractHttpResponse.close
34-
// 不关闭 response 的话会遇到重复写响应体的情况
35-
invokeMethod(response, "close", null, null);
3652
} catch (Throwable e) {
3753
e.printStackTrace();
3854
} finally {
@@ -84,4 +100,19 @@ public static Object getFieldValue(Object obj, String name) throws Exception {
84100
}
85101
throw new NoSuchFieldException(obj.getClass().getName() + " Field not found: " + name);
86102
}
103+
104+
@SuppressWarnings("all")
105+
private String getErrorMessage(Throwable throwable) {
106+
PrintStream printStream = null;
107+
try {
108+
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
109+
printStream = new PrintStream(outputStream);
110+
throwable.printStackTrace(printStream);
111+
return outputStream.toString();
112+
} finally {
113+
if (printStream != null) {
114+
printStream.close();
115+
}
116+
}
117+
}
87118
}

generator/src/main/java/com/reajason/javaweb/probe/payload/response/SpringWebMvcWriter.java

Lines changed: 34 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
11
package com.reajason.javaweb.probe.payload.response;
22

3+
import java.io.ByteArrayOutputStream;
4+
import java.io.OutputStream;
5+
import java.io.PrintStream;
36
import java.io.PrintWriter;
47
import java.lang.reflect.Field;
58
import java.lang.reflect.Method;
@@ -23,17 +26,26 @@ public SpringWebMvcWriter() {
2326
Object response = invokeMethod(requestAttributes, "getResponse", null, null);
2427
String data = getDataFromReq(request);
2528
if (data != null && !data.isEmpty()) {
26-
PrintWriter writer = (PrintWriter) invokeMethod(response, "getWriter", null, null);
29+
String result = "";
2730
try {
28-
writer.write(run(data));
31+
result = run(data);
2932
} catch (Throwable e) {
30-
e.printStackTrace(writer);
33+
result = getErrorMessage(e);
34+
}
35+
if (result != null) {
36+
try {
37+
OutputStream outputStream = (OutputStream) invokeMethod(response, "getOutputStream", null, null);
38+
outputStream.write(result.getBytes());
39+
outputStream.flush();
40+
outputStream.close();
41+
} catch (Throwable e) {
42+
PrintWriter writer = (PrintWriter) invokeMethod(response, "getWriter", null, null);
43+
writer.write(result);
44+
writer.flush();
45+
writer.close();
46+
}
3147
}
32-
writer.flush();
33-
writer.close();
34-
return;
3548
}
36-
3749
} catch (Throwable e) {
3850
e.printStackTrace();
3951
} finally {
@@ -85,4 +97,19 @@ public static Object getFieldValue(Object obj, String name) throws Exception {
8597
}
8698
throw new NoSuchFieldException(obj.getClass().getName() + " Field not found: " + name);
8799
}
100+
101+
@SuppressWarnings("all")
102+
private String getErrorMessage(Throwable throwable) {
103+
PrintStream printStream = null;
104+
try {
105+
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
106+
printStream = new PrintStream(outputStream);
107+
throwable.printStackTrace(printStream);
108+
return outputStream.toString();
109+
} finally {
110+
if (printStream != null) {
111+
printStream.close();
112+
}
113+
}
114+
}
88115
}

0 commit comments

Comments
 (0)