How do I configure Keep-Alive in CXF or jaxrs:client - cxf

I'm using CXF and jaxrs:client to connect to a Restful service. However, the restful service timesout after 300 seconds - it's DDOS mitigation at their end. According to the owners of the Restful service, if we include a Keep-Alive header in oyr request, the timeout won't occur. How can I configure Keep-Alive in CXF or jaxrs:client calls?
Thanks in advance
Angus

You can set a header for a jaxrs:client usign the jaxrs:headers tag
<jaxrs:client id="" serviceClass="" address="" inheritHeaders="true">
<jaxrs:headers>
<entry key="Connection" value="keep-alive"/>
</jaxrs:headers>
</jaxrs:client>
Also you can configure timeouts in the http-conf:client tag of the http:conduit element
<http-conf:conduit name="*">
<http-conf:client Connection="Keep-Alive"
ConnectionTimeout="0"
ReceiveTimeout="0" />
</http-conf:conduit>
The complete list of parameters is here.
Note that keep-alive is the default. ReceiveTimeout 0 means no timeout. Default value is 30000 (30s)

Related

How to get AMQP Message properties in Apache Camel AMQP Component

I have a Springboot application using Apache Camel AMQP component to comsume messages from a Solace Queue. To send a message to the Queue I use Postman and the Solace REST API. In order to differentiate the message type I add Content-Type to the header of the Http request in Postman. I used SDKPerf to check the message header consumed from solace and the message header is found under "HTTP Content Type" along with other headers.
However, I can't seem to find a way to get this Content-Type from Camel Side. In the documentation it says
String header = exchange.getIn().getHeader(Exchange.CONTENT_TYPE, String.class);
However this always produces null. Any Ideas how to get the message properties in Camel?
EDIT: I think it's actually due to the fact that Camel is using QPid JMS, and there is no JMS API way of getting the Content Type, it's not in the spec. Even though AMQP 1.0 does support content-type as a property. But yeah, my suggestion of a custom property below is still probably the way I would go.
https://camel.apache.org/components/3.20.x/amqp-component.html
https://www.amqp.org/sites/amqp.org/files/amqp.pdf
Edited for clarity & corrections. TL/DR: use a custom user property header.
The SMF Content Type header in the original (REST) message is passed through to the consumed AMQP message as a property content-type, however the JMS API spec does not expose this; there is no way in standard JMS to retrieve this value. It is, however, used by the broker to set the type of message (e.g. TextMessage). Check "Content-Type Mapping to Solace Message Types" in the Solace docs.
Using Solace's SDKPerf AMQP JMS edition to dump the received message to console (note this uses QPid libraries):
./sdkperf_jmsamqp.sh -cip=amqp://localhost:5672 -stl=a/b/c
-md -q
curl http://localhost:9000/TOPIC/a/b/c -d 'hello' -H 'Content-Type: text'
^^^^^^^^^^^^^^^^^^ Start Message ^^^^^^^^^^^^^^^^^^^^^^^^^^^
JMSDeliveryMode: PERSISTENT
JMSDestination: a/b/c
JMSExpiration: 0
JMSPriority: 4
JMSTimestamp: 0
JMSRedelivered: false
JMSCorrelationID: null
JMSMessageID: null
JMSReplyTo: null
JMSType: null
JMSProperties: {JMSXDeliveryCount:1;}
Object Type: TextMessage
Text: len=5
hello
The header does not get mapped through, but does get used to set the message type. If I remove that HTTP header, the received AMQP message is binary. But since other types of Content-Types also map to TextMessages (e.g. application/json, application/xml, etc.), the fact you're receiving a TextMessage is not enough to infer exactly what Content-Type you published your REST message with.
For completeness, I used WireShark with an AMQP decoder, and you can see the header present on the received AMQP message:
Frame 3: 218 bytes on wire (1744 bits), 218 bytes captured (1744 bits) on interface \Device\NPF_Loopback, id 0
Null/Loopback
Internet Protocol Version 4, Src: 127.0.0.1, Dst: 127.0.0.1
Transmission Control Protocol, Src Port: 5672, Dst Port: 60662, Seq: 2, Ack: 1, Len: 174
Advanced Message Queueing Protocol
Length: 174
Doff: 2
Type: AMQP (0)
Channel: 2
Performative: transfer (20)
Arguments (5)
Message-Header
Durable: True
Message-Annotations (map of 1 element)
x-opt-jms-dest (byte): 1
Message-Properties
To: a/b/c
Content-Type: text <----------
Application-Properties (map of 1 element)
AaronEncoding (str8-utf8): CustomText
AMQP-Value (str32-utf8): hello
So my suggestion is this:
Set an additional custom header, a User Property, which will get passed through to the AMQP message:
curl http://localhost:9000/TOPIC/a/b/c -d 'hello' -H 'Solace-User-Property-AaronEncoding: CustomText' -H 'Content-Type: text'
JMSDestination: a/b/c
JMSProperties: {AaronEncoding:CustomText;JMSXDeliveryCount:1;}
Object Type: TextMessage
Text: len=5
hello
My always-goto guide for Solace REST interactions: https://docs.solace.com/API/RESTMessagingPrtl/Solace-REST-Message-Encoding.htm
Hope that helps!
It may have a different name in Camel. Try either printing all the headers or stop it in the debugger and examine the incoming message.

Angular Put request not working with Laravel 5.3 hosted on azure

I am sending PUT request on my Laravel 5.3 application that is hosted on azure webapps. But I receive a delayed response 504 (Gateway Timeout). While It is working on POSTman (chrome extension).
this is my angular code:
put : function (id, params) {
params.api_token = TOKEN;
return $http.put(url+'/lead/'+id, params);
},
And running this would give me 504 (Gateway Timeout) after 1 min
I have also setup web.config to handle PUT & DELETE. Described here in detail.
<handlers>
<remove name="PHP54_via_FastCGI" />
<add name="PHP54_via_FastCGI" path="*.php" verb="GET, PUT, POST, HEAD, OPTIONS, TRACE, PROPFIND, PROPPATCH, MKCOL, COPY, MOVE, LOCK, UNLOCK" modules="FastCgiModule" scriptProcessor="D:\Program Files (x86)\PHP\v5.4\php-cgi.exe" resourceType="Either" requireAccess="Script" />
</handlers>
So, Because Apache and IIS servers are different. IIS does not handle PUT and DELETE by default. It also handles params for PUT request differently.
Instead of body, you need to send it in a query string like ../resource?param1=value1. AKA x-www-form-urlencoded This article explains it thoroughly
As of angular, this worked for me.
function (id, params) {
params.api_token = TOKEN;
var params = $httpParamSerializerJQLike(params);
return $http.put(url+'/lead/'+id+'?'+params);
}
NOTE: In addition, your web.config does require <handler> tags to be able to handle these requests. which is defined here

SoapHeaders are not passed in the SoapMessage to CXF service in apache camel

I am not getting the SoapHeader tags in the Soap message in the cxf service invoked. My current code is as below:
I have defined a cxf:cxfEndpoint for the service:
<cxf:cxfEndpoint id="testService" address="${testserviceurl}"
serviceClass="com.test.service.class" wsdlURL="test.wsdl"
endpointName="ns:test" serviceName="ns:TestService"
xmlns:ns="target.name.space.of.the.service">
<cxf:properties>
<entry key="dataFormat" value="PAYLOAD" />
</cxf:properties>
</cxf:cxfEndpoint>
And then before invoking my cxf endpoint, I have set the SoapHeader as:
CxfPayload<SoapHeader> payload = exchange.getIn().getBody(
CxfPayload.class);
List<SoapHeader> headers = payload.getHeaders();
SoapHeader header = new SoapHeader(new QName("HeaderName"), "Test");
headers.add(header);
I have also tried the approach:
List<SoapHeader> soapHeaders = CastUtils.cast((List<?>) exchange
.getIn().getHeader(Header.HEADER_LIST));
if (soapHeaders == null) {
// we just create a new soap headers in case the header is null
soapHeaders = new ArrayList<SoapHeader>();
}
SoapHeader header = new SoapHeader(new QName("HeaderName"),
"Test");
header.setDirection(Direction.DIRECTION_OUT);
soapHeaders.add(header);
Can anyone please help on what is wrong with this?
When you make any synchronous request through cxf client. It uses jdk's Http connection client to communicate over http.
As per this jira defect jdk does't allow to set header.
If you want to set headers you can do it by setting VM parameter
sun.net.http.allowRestrictedHeaders=true
If you use cxf in async mode it uses apache's HttpAsyncClient. This allows you to set the request headers.
Hope this helps.

Mitigating reflected XSS in node/express requests for static assets

I've run a pen test tool (Burp) against my node(express)/angular application and it identified a reflected XSS vulnerability specifically when attempting a GET request for static assets (noticeably vulnerabilities were not found for any of the requests being made when a user interacts with the application).
The issue detail is:
The name of an arbitrarily supplied URL parameter is copied into a
JavaScript expression which is not encapsulated in any quotation
marks. The payload 41b68(a)184a9=1 was submitted in the name of an
arbitrarily supplied URL parameter. This input was echoed unmodified
in the application's response.
This behavior demonstrates that it is possible to inject JavaScript
commands into the returned document. An attempt was made to identify a
full proof-of-concept attack for injecting arbitrary JavaScript but
this was not successful. You should manually examine the application's
behavior and attempt to identify any unusual input validation or other
obstacles that may be in place.
The vulnerability was tested by passing an arbitrary url parameter to the request like so:
GET /images/?41b68(a)184a9=1
The response was:
HTTP/1.1 404 Not Found
X-Content-Security-Policy: connect-src 'self'; default-src 'self'; font-src 'self'; frame-src; img-src 'self' *.google-analytics.com; media-src; object-src; script-src 'self' 'unsafe-eval' *.google-analytics.com; style-src 'self' 'unsafe-inline'
X-XSS-Protection: 1; mode=block
X-Frame-Options: DENY
Strict-Transport-Security: max-age=10886400; includeSubDomains; preload
X-Download-Options: noopen
X-Content-Type-Options: nosniff
Content-Type: text/html; charset=utf-8
Content-Length: 52
Date: Wed, 08 Oct 2015 10:46:43 GMT
Connection: close
Cannot GET /images/?41b68(a)184a9=1
You can see that I have CSP in place (using Helmet to implement) and other protections against exploits. The app is served over https, but no user auth is required. CSP restricts request to the app's domain only plus google analytics.
The pen test report advises validating input (I am, but surely that would make requests including data sent by a user unsafe if I wasn't?), and encoding html which angular does by default.
I'm really struggling to find a solution to preventing or mitigating this for those requests for static assets:
Should I whitelist all requests for my application under csp?
Can I even do this, or will it only whitelist domains?
Can/should all responses from node/express to requests for static assets be encoded in some way?
The report states that "The name of an arbitrarily supplied URL parameter is copied into a JavaScript expression which is not encapsulated in any quotation marks". Could this expression be somewhere in the express code that handles returning static assets?
Or that GET request param can somehow be evaluated in my application code?
Update
Having done some investigation into this it seems that at least part of the mitigation is to escape data in url param values and sanitize the input in the url.
Escaping of the url is already in place so:
curl 'http://mydomain/images/?<script>alert('hello')</script>'
returns
Cannot GET /images/?<script>alert(hello)</script>
I've also put express-sanitized in place on top of this.
However, if I curl the original test the request param is still reflected back.
curl 'http://mydomain/images/?41b68(a)184a9=1'
Cannot GET /images/?41b68(a)184a9=1
Which you would expect because html is not being inserted into the url.
The responses to GET requests for static assets are all handled by app.use(express.static('static-dir')) so the query is passed into this. express.static is based on serve-static which depends on parseurl.
The cause of the issue is that for invalid GET requests express will return something like:
Cannot GET /pathname/?yourQueryString
Which in many cases is a valid response, even for serving static assets. However, in my case and I'm sure for others the only valid requests for static assets will be something like:
GET /pathname/your-file.jpg
I have a custom 404 handler that returns a data object:
var data = {
status: 404,
message: 'Not Found',
description: description,
url: req.url
};
This is only handled for invalid template requests in app.js with:
app.use('/template-path/*', function(req, res, next) {
custom404.send404(req, res);
});
I've now added explicit handlers for requests to static folders:
app.use('/static-path/*', function(req, res, next) {
custom404.send404(req, res);
});
Optionally I could also strip out request query params before the 404 is returned:
var data = {
status: 404,
message: 'Not Found',
description: description,
url: url.parse(req.url).pathname // needs a var url = require('url')
};

Are GET request header fields and values case-sensitive?

I'm working on a programing assignment regarding using GET request.
I am using C.
I wonder if any headers fields and values of GET packet have to be capitalized?
For example:
GET / HTTP/1.1
Connection: Keep-Alive
vs
get / HTTP/1.1
connection: keep-alive
HTTP method names are case-sensitive:
The Method token indicates the method
to be performed on the resource
identified by the Request-URI. The
method is case-sensitive.
HTTP header names are case-insensitive.

Resources