Skip to content

Commit c558f30

Browse files
committed
CAMEL-9309: Make it easier to turn on|off java transport over http
1 parent 735ee02 commit c558f30

13 files changed

Lines changed: 228 additions & 18 deletions

File tree

components/camel-ahc/src/main/java/org/apache/camel/component/ahc/AhcEndpoint.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -179,6 +179,9 @@ public boolean isTransferException() {
179179
* in the response as a application/x-java-serialized-object content type (for example using Jetty or Servlet Camel components).
180180
* On the producer side the exception will be deserialized and thrown as is, instead of the AhcOperationFailedException.
181181
* The caused exception is required to be serialized.
182+
* <p/>
183+
* This is by default turned off. If you enable this then be aware that Java will deserialize the incoming
184+
* data from the request to Java and that can be a potential security risk.
182185
*/
183186
public void setTransferException(boolean transferException) {
184187
this.transferException = transferException;

components/camel-http-common/src/main/java/org/apache/camel/http/common/DefaultHttpBinding.java

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -531,6 +531,14 @@ public void setTransferException(boolean transferException) {
531531
this.transferException = transferException;
532532
}
533533

534+
public boolean isAllowJavaSerializedObject() {
535+
return allowJavaSerializedObject;
536+
}
537+
538+
public void setAllowJavaSerializedObject(boolean allowJavaSerializedObject) {
539+
this.allowJavaSerializedObject = allowJavaSerializedObject;
540+
}
541+
534542
public HeaderFilterStrategy getHeaderFilterStrategy() {
535543
return headerFilterStrategy;
536544
}

components/camel-http-common/src/main/java/org/apache/camel/http/common/HttpBinding.java

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -118,9 +118,20 @@ public interface HttpBinding {
118118
* serialized in the response as a application/x-java-serialized-object content type (for example using Jetty or
119119
* Servlet Camel components). On the producer side the exception will be deserialized and thrown as is,
120120
* instead of the HttpOperationFailedException. The caused exception is required to be serialized.
121+
* <p/>
122+
* This is by default turned off. If you enable this then be aware that Java will deserialize the incoming
123+
* data from the request to Java and that can be a potential security risk.
121124
*/
122125
boolean isTransferException();
123126

127+
/**
128+
* Whether to allow java serialization when a request uses context-type=application/x-java-serialized-object
129+
* <p/>
130+
* This is by default turned off. If you enable this then be aware that Java will deserialize the incoming
131+
* data from the request to Java and that can be a potential security risk.
132+
*/
133+
boolean isAllowJavaSerializedObject();
134+
124135
/**
125136
* Whether to eager check whether the HTTP requests has content if the content-length header is 0 or not present.
126137
* This can be turned on in case HTTP clients do not send streamed data.
@@ -138,9 +149,22 @@ public interface HttpBinding {
138149
* serialized in the response as a application/x-java-serialized-object content type (for example using Jetty or
139150
* Servlet Camel components). On the producer side the exception will be deserialized and thrown as is,
140151
* instead of the HttpOperationFailedException. The caused exception is required to be serialized.
152+
* <p/>
153+
* This is by default turned off. If you enable this then be aware that Java will deserialize the incoming
154+
* data from the request to Java and that can be a potential security risk.
141155
*/
142156
void setTransferException(boolean transferException);
143157

158+
/**
159+
* Whether to allow java serialization when a request uses context-type=application/x-java-serialized-object
160+
* <p/>
161+
* This is by default turned off. If you enable this then be aware that Java will deserialize the incoming
162+
* data from the request to Java and that can be a potential security risk.
163+
*
164+
* @param allowJavaSerializedObject <tt>true</tt> to allow serializing java objects
165+
*/
166+
void setAllowJavaSerializedObject(boolean allowJavaSerializedObject);
167+
144168
/**
145169
* Gets the header filter strategy
146170
*

components/camel-http-common/src/main/java/org/apache/camel/http/common/HttpCommonEndpoint.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,6 @@
1919
import java.net.URI;
2020
import java.net.URISyntaxException;
2121

22-
import org.apache.camel.Component;
2322
import org.apache.camel.impl.DefaultEndpoint;
2423
import org.apache.camel.spi.HeaderFilterStrategy;
2524
import org.apache.camel.spi.HeaderFilterStrategyAware;
@@ -142,6 +141,9 @@ public HttpBinding getBinding() {
142141
binding = new DefaultHttpBinding();
143142
binding.setHeaderFilterStrategy(getHeaderFilterStrategy());
144143
binding.setTransferException(isTransferException());
144+
if (getComponent() != null) {
145+
binding.setAllowJavaSerializedObject(getComponent().isAllowJavaSerializedObject());
146+
}
145147
binding.setEagerCheckContentAvailable(isEagerCheckContentAvailable());
146148
}
147149
return binding;

components/camel-jetty-common/src/main/java/org/apache/camel/component/jetty/CamelContinuationServlet.java

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
import org.apache.camel.Exchange;
2929
import org.apache.camel.ExchangePattern;
3030
import org.apache.camel.http.common.CamelServlet;
31+
import org.apache.camel.http.common.HttpConstants;
3132
import org.apache.camel.http.common.HttpConsumer;
3233
import org.apache.camel.http.common.HttpHelper;
3334
import org.apache.camel.http.common.HttpMessage;
@@ -85,6 +86,14 @@ protected void service(final HttpServletRequest request, final HttpServletRespon
8586
response.sendError(HttpServletResponse.SC_METHOD_NOT_ALLOWED);
8687
return;
8788
}
89+
90+
// we do not support java serialized objects unless explicit enabled
91+
String contentType = request.getContentType();
92+
if (HttpConstants.CONTENT_TYPE_JAVA_SERIALIZED_OBJECT.equals(contentType) && !consumer.getEndpoint().getComponent().isAllowJavaSerializedObject()) {
93+
System.out.println("415 miser !!!");
94+
response.sendError(HttpServletResponse.SC_UNSUPPORTED_MEDIA_TYPE);
95+
return;
96+
}
8897

8998
final Exchange result = (Exchange) request.getAttribute(EXCHANGE_ATTRIBUTE_NAME);
9099
if (result == null) {

components/camel-jetty-common/src/main/java/org/apache/camel/component/jetty/DefaultJettyHttpBinding.java

Lines changed: 20 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@ public class DefaultJettyHttpBinding implements JettyHttpBinding {
4646
private HeaderFilterStrategy httpProtocolHeaderFilterStrategy = new HttpProtocolHeaderFilterStrategy();
4747
private boolean throwExceptionOnFailure;
4848
private boolean transferException;
49+
private boolean allowJavaSerializedObject;
4950
private String okStatusCodeRange;
5051

5152
public DefaultJettyHttpBinding() {
@@ -101,6 +102,14 @@ public void setTransferException(boolean transferException) {
101102
this.transferException = transferException;
102103
}
103104

105+
public boolean isAllowJavaSerializedObject() {
106+
return allowJavaSerializedObject;
107+
}
108+
109+
public void setAllowJavaSerializedObject(boolean allowJavaSerializedObject) {
110+
this.allowJavaSerializedObject = allowJavaSerializedObject;
111+
}
112+
104113
public String getOkStatusCodeRange() {
105114
return okStatusCodeRange;
106115
}
@@ -183,11 +192,17 @@ protected Object extractResponseBody(Exchange exchange, JettyContentExchange htt
183192

184193
// if content type is serialized java object, then de-serialize it to a Java object
185194
if (contentType != null && HttpConstants.CONTENT_TYPE_JAVA_SERIALIZED_OBJECT.equals(contentType)) {
186-
try {
187-
InputStream is = exchange.getContext().getTypeConverter().mandatoryConvertTo(InputStream.class, httpExchange.getResponseContentBytes());
188-
return HttpHelper.deserializeJavaObjectFromStream(is, exchange.getContext());
189-
} catch (Exception e) {
190-
throw new RuntimeCamelException("Cannot deserialize body to Java object", e);
195+
// only deserialize java if allowed
196+
if (isAllowJavaSerializedObject() || isTransferException()) {
197+
try {
198+
InputStream is = exchange.getContext().getTypeConverter().mandatoryConvertTo(InputStream.class, httpExchange.getResponseContentBytes());
199+
return HttpHelper.deserializeJavaObjectFromStream(is, exchange.getContext());
200+
} catch (Exception e) {
201+
throw new RuntimeCamelException("Cannot deserialize body to Java object", e);
202+
}
203+
} else {
204+
// empty body
205+
return null;
191206
}
192207
} else {
193208
// just grab the raw content body

components/camel-jetty-common/src/main/java/org/apache/camel/component/jetty/JettyHttpBinding.java

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,9 @@ public interface JettyHttpBinding {
7070
/**
7171
* Whether to transfer exception back as a serialized java object
7272
* if processing failed due to an exception
73+
* <p/>
74+
* This is by default turned off. If you enable this then be aware that Java will deserialize the incoming
75+
* data from the request to Java and that can be a potential security risk.
7376
*
7477
* @param transferException <tt>true</tt> to transfer exception
7578
*/
@@ -78,11 +81,32 @@ public interface JettyHttpBinding {
7881
/**
7982
* Whether to transfer exception back as a serialized java object
8083
* if processing failed due to an exception
84+
* <p/>
85+
* This is by default turned off. If you enable this then be aware that Java will deserialize the incoming
86+
* data from the request to Java and that can be a potential security risk.
8187
*
8288
* @return <tt>true</tt> to transfer exception
8389
*/
8490
boolean isTransferException();
8591

92+
/**
93+
* Whether to allow java serialization when a request uses context-type=application/x-java-serialized-object
94+
* <p/>
95+
* This is by default turned off. If you enable this then be aware that Java will deserialize the incoming
96+
* data from the request to Java and that can be a potential security risk.
97+
*
98+
* @param allowJavaSerializedObject <tt>true</tt> to allow serializing java objects
99+
*/
100+
void setAllowJavaSerializedObject(boolean allowJavaSerializedObject);
101+
102+
/**
103+
* Whether to allow java serialization when a request uses context-type=application/x-java-serialized-object
104+
* <p/>
105+
* This is by default turned off. If you enable this then be aware that Java will deserialize the incoming
106+
* data from the request to Java and that can be a potential security risk.
107+
*/
108+
boolean isAllowJavaSerializedObject();
109+
86110
/**
87111
* The status codes which is considered a success response. The values are inclusive. The range must be defined as from-to with the dash included.
88112
* <p/>

components/camel-jetty-common/src/main/java/org/apache/camel/component/jetty/JettyHttpEndpoint.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -192,6 +192,9 @@ public synchronized JettyHttpBinding getJettyBinding(HttpClient httpClient) {
192192
jettyBinding.setHeaderFilterStrategy(getHeaderFilterStrategy());
193193
jettyBinding.setThrowExceptionOnFailure(isThrowExceptionOnFailure());
194194
jettyBinding.setTransferException(isTransferException());
195+
if (getComponent() != null) {
196+
jettyBinding.setAllowJavaSerializedObject(getComponent().isAllowJavaSerializedObject());
197+
}
195198
jettyBinding.setOkStatusCodeRange(getOkStatusCodeRange());
196199
}
197200
return jettyBinding;

components/camel-jetty-common/src/main/java/org/apache/camel/component/jetty/JettyHttpProducer.java

Lines changed: 14 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -30,9 +30,9 @@
3030
import org.apache.camel.Endpoint;
3131
import org.apache.camel.Exchange;
3232
import org.apache.camel.Message;
33+
import org.apache.camel.RuntimeCamelException;
3334
import org.apache.camel.http.common.HttpConstants;
3435
import org.apache.camel.http.common.HttpHelper;
35-
import org.apache.camel.http.common.HttpMethods;
3636
import org.apache.camel.impl.DefaultAsyncProducer;
3737
import org.apache.camel.spi.HeaderFilterStrategy;
3838
import org.apache.camel.util.ExchangeHelper;
@@ -138,17 +138,20 @@ private void processInternal(Exchange exchange, AsyncCallback callback) throws E
138138
if (contentType != null) {
139139
httpExchange.setRequestContentType(contentType);
140140
}
141-
142141
if (contentType != null && HttpConstants.CONTENT_TYPE_JAVA_SERIALIZED_OBJECT.equals(contentType)) {
143-
// serialized java object
144-
Serializable obj = exchange.getIn().getMandatoryBody(Serializable.class);
145-
// write object to output stream
146-
ByteArrayOutputStream bos = new ByteArrayOutputStream();
147-
try {
148-
HttpHelper.writeObjectToStream(bos, obj);
149-
httpExchange.setRequestContent(bos.toByteArray());
150-
} finally {
151-
IOHelper.close(bos, "body", LOG);
142+
if (getEndpoint().getComponent().isAllowJavaSerializedObject() || getEndpoint().isTransferException()) {
143+
// serialized java object
144+
Serializable obj = exchange.getIn().getMandatoryBody(Serializable.class);
145+
// write object to output stream
146+
ByteArrayOutputStream bos = new ByteArrayOutputStream();
147+
try {
148+
HttpHelper.writeObjectToStream(bos, obj);
149+
httpExchange.setRequestContent(bos.toByteArray());
150+
} finally {
151+
IOHelper.close(bos, "body", LOG);
152+
}
153+
} else {
154+
throw new RuntimeCamelException("Content-type " + HttpConstants.CONTENT_TYPE_JAVA_SERIALIZED_OBJECT + " is not allowed");
152155
}
153156
} else {
154157
Object body = exchange.getIn().getBody();

components/camel-jetty9/src/main/java/org/apache/camel/component/jetty9/JettyHttpEndpoint9.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,9 @@ public HttpBinding getBinding() {
4040
if (this.binding == null) {
4141
this.binding = new AttachmentHttpBinding();
4242
this.binding.setTransferException(isTransferException());
43+
if (getComponent() != null) {
44+
this.binding.setAllowJavaSerializedObject(getComponent().isAllowJavaSerializedObject());
45+
}
4346
this.binding.setHeaderFilterStrategy(getHeaderFilterStrategy());
4447
}
4548
return this.binding;

0 commit comments

Comments
 (0)