When I create a cxf client to call a SOAP web service it returns connection refused or Unexpected end of file from server. The thing is though, it just happens on the first request, afterwards it's like the client is "warmed up" and actually starts working.
Any idea why this is happening?
...
if(port == null) {
JaxWsProxyFactoryBean factory = new JaxWsProxyFactoryBean();
factory.getInInterceptors().add(new LoggingInInterceptor());
factory.getOutInterceptors().add(new LoggingOutInterceptor());
factory.setAddress("http://localhost:9000/helloWorld");
port = factory.create(HelloWorld.class);
...
Client client= ClientProxy.getClient(port);
HTTPConduit http = (HTTPConduit) client.getConduit();
HTTPClientPolicy httpClientPolicy = new HTTPClientPolicy();
httpClientPolicy.setAllowChunking(false);
http.setClient(httpClientPolicy);
}
port.someMethod(); // fails on first run, but succeeds on all following runs
...
Removing the if-statement would cause the client to fail on every call not just the first. I'm really stuck and would appreciate any help.
It seems that the issue was caused through TLS 1.2. In Java8 the default TLS version changed from TLSv1 to TLSv1.2. TLS 1.2 didn't seem to work even with the latest version of CXF (3.1.7). So the Solution was to set the TLS version to be used for CXF:
...
HTTPClientPolicy httpClientPolicy = new HTTPClientPolicy();
httpClientPolicy.setAllowChunking(false);
httpClientPolicy.setAutoRedirect(true);
httpClientPolicy.setConnection(ConnectionType.KEEP_ALIVE);
String proxyUrl = "http://proxy.com";
String proxyPortString = "8080";
HTTPConduit http = (HTTPConduit)client.getConduit();
SSLContext sslContext = SSLContext.getInstance("TLSv1");
sslContext.init(null, null, null);
HttpsURLConnection.setDefaultSSLSocketFactory(sslContext.getSocketFactory());
TLSClientParameters tlsClientParameters = new TLSClientParameters();
tlsClientParameters.setUseHttpsURLConnectionDefaultSslSocketFactory(true);
http.setTlsClientParameters(tlsClientParameters);
http.setClient(httpClientPolicy);
Related
I have an http2 server at https://ec2-52-57-54-142.eu-central-1.compute.amazonaws.com/ with a self-signed cert. And I have a jetty http2 client that simply posts things to it. For some reason, I'm not getting ignoring self-signed cert to work. Here's a snippet of relevant code
SslContextFactory factory = new SslContextFactory(true);
factory.setTrustAll(true);
factory.setValidateCerts(false);
factory.setValidatePeerCerts(false);
factory.setEndpointIdentificationAlgorithm(null);
SSLContext sslContext = factory.getSslContext();
if(null == sslContext) {
sslContext = SSLContext.getInstance("TLS");
}
TrustManager[] verifiers = new TrustManager[] {...// some dummy trust manager that always passes};
sslContext.init(null, verifiers, null);
factory.setSslContext(sslContext);
HttpClientTransportOverHTTP2 httpClientTransportOverHTTP2
= new HttpClientTransportOverHTTP2(new HTTP2Client());
HttpClient httpClient = new HttpClient(httpClientTransportOverHTTP2, factory);
Request request = httpClient.POST(destination);
ContentProvider contentProvider = new InputStreamContentProvider(new StringInputStream(payload));
request.content(contentProvider);
ContentResponse response = request.send();
And I get these stacktrace
Caused by: java.util.concurrent.ExecutionException: java.nio.channels.ClosedChannelException
at org.eclipse.jetty.client.util.FutureResponseListener.getResult(FutureResponseListener.java:118)
at org.eclipse.jetty.client.util.FutureResponseListener.get(FutureResponseListener.java:101)
at org.eclipse.jetty.client.HttpRequest.send(HttpRequest.java:652)
at my code
... 34 more
Caused by: java.nio.channels.ClosedChannelException
at org.eclipse.jetty.io.WriteFlusher.onClose(WriteFlusher.java:498)
at org.eclipse.jetty.io.ssl.SslConnection$DecryptedEndPoint.onIncompleteFlush(SslConnection.java:409)
at org.eclipse.jetty.io.AbstractEndPoint$2.onIncompleteFlush(AbstractEndPoint.java:54)
at org.eclipse.jetty.io.WriteFlusher.write(WriteFlusher.java:322)
at org.eclipse.jetty.io.AbstractEndPoint.write(AbstractEndPoint.java:140)
at org.eclipse.jetty.http2.HTTP2Flusher.process(HTTP2Flusher.java:243)
at org.eclipse.jetty.util.IteratingCallback.processing(IteratingCallback.java:241)
at org.eclipse.jetty.util.IteratingCallback.succeeded(IteratingCallback.java:365)
at org.eclipse.jetty.http2.HTTP2Flusher.succeeded(HTTP2Flusher.java:258)
at org.eclipse.jetty.io.WriteFlusher$PendingState.complete(WriteFlusher.java:269)
at org.eclipse.jetty.io.WriteFlusher.completeWrite(WriteFlusher.java:394)
at org.eclipse.jetty.io.ssl.SslConnection$1.run(SslConnection.java:101)
at org.eclipse.jetty.util.thread.QueuedThreadPool.runJob(QueuedThreadPool.java:671)
at org.eclipse.jetty.util.thread.QueuedThreadPool$2.run(QueuedThreadPool.java:589)
... 1 more
When I step through things with a debugger, I see something about NOT_HANDSHAKE in one of the connection objects.
I really don't care about verifying anything. I just want to connect over HTTP2/TLS. I searched for many different terms, but they all end up with more or less the same thing (setTrustAll, custom TrustManager, etc)
Any help? Thanks!
P.S. Jetty version 9.3.12
Your client code is correct, although redundant.
It is enough to do:
SslContextFactory sslContextFactory = new SslContextFactory(true);
HTTP2Client http2Client = new HTTP2Client();
HttpClient httpClient = new HttpClient(new HttpClientTransportOverHTTP2(http2Client), sslContextFactory);
httpClient.start();
ContentResponse response = httpClient.GET("https://ec2-52-57-54-142.eu-central-1.compute.amazonaws.com/");
If you enable DEBUG logging on the Jetty HTTP/2 client, you will see that the client receives:
2016-10-05 09:20:33.102:DBUG:oejhp.Parser:qtp1897115967-15: Parsed GO_AWAY frame header from java.nio.HeapByteBuffer[pos=9 lim=35 cap=16384]
2016-10-05 09:20:33.103:DBUG:oejh.HTTP2Session:qtp1897115967-15: Received GoAwayFrame#3bc447d3,0/INADEQUATE_SECURITY_ERROR/Unknown error code
So the problem is that the server thinks that the security is inadequate (the GOAWAY frame arrives with error code INADEQUATE_SECURITY_ERROR).
At this point, the problem is on the server. You have to figure out why the server thinks the security is inadequate. Probably just a matter of configuration on the server.
Try
transport.setUseALPN(false);
The following code is what i have used to add Connection and Receive timeout to my CXF Web Service,Receive timeout works fine but Connection timeout does not and i think i have a clue why ,the service tries to connect at line1 but the code for setting timeout follows the code,as it always gets stuck at line1 ,how will it ever set a timeout at line2.Please share if there is any other way to set the timeout.
CalculatorService cal = new CalculatorService(); //line1
Calculator port= cal.getCalculatorPort();
Client cl = ClientProxy.getClient(port);
HTTPConduit http = (HTTPConduit)cl.getConduit();
HTTPClientPolicy httpClientPolicy = new HTTPClientPolicy();
httpClientPolicy.setConnectionTimeout(5000); //line2
httpClientPolicy.setReceiveTimeout(4000);
http.setClient(httpClientPolicy);
port.add(1, 2);
I am trying to connect to an HTTPs URL with Apache HttpClient 4.1....
HttpGet httpget = new HttpGet("https://federation/galaxy-class/enterprise/getSheildFrequencies");
DefaultHttpClient httpclient = new DefaultHttpClient();
HttpResponse response = httpclient.execute(httpget);
During the connection process, I get the below exception...
Caught: javax.net.ssl.SSLPeerUnverifiedException: peer not authenticated
When I turn on debugging, I see the below..
main, WRITE: TLSv1 Handshake, length = 81
main, WRITE: SSLv2 client hello message, length = 110
main, handling exception: java.net.SocketException: Connection reset
So it seems like my client did the handshake in TLSv1 but then sent a client hello in SSLv2 which the server didn't like (it dropped the connection because it doesn't support SSLv2 backwards compatibility mode).
Is there any way to tell Apache HttpClient not to do that? Or is this something configured at the underlying JRE (I am using 1.6)?
UPDATE
As bmargulies suggested, I tried to make my own socket factory and configure it to only allow the protocols I want....
def supportedProtocols = new String[2]
supportedProtocols[0] = 'SSLv3'
supportedProtocols[1] = 'TLSv1'
SSLConnectionSocketFactory socketFactory = new SSLConnectionSocketFactory(
SSLContext.getDefault(),supportedProtocols,
null,
SSLConnectionSocketFactory.getDefaultHostnameVerifier());
Registry<ConnectionSocketFactory> socketFactoryRegistry = RegistryBuilder.<ConnectionSocketFactory>create()
.register("http", PlainConnectionSocketFactory.getSocketFactory())
.register("https", socketFactory)
.build();
PoolingHttpClientConnectionManager cm = new PoolingHttpClientConnectionManager(socketFactoryRegistry);
CloseableHttpClient client = HttpClients.custom().setConnectionManager(cm).build();
HttpResponse response = client.execute(httpget);
But this gives another exception...
javax.net.ssl.SSLException: java.lang.RuntimeException: Could not generate DH keypair
Use the current version of the http components
Use the HttpClientBuilder
Make your own socket factory and configure it to only allow the protocols you want.
Registry<ConnectionSocketFactory> socketFactoryRegistry = RegistryBuilder.<ConnectionSocketFactory>create()
.register("http", PlainSocketFactory.INSTANCE)
.register("https", new SSLSocketFactory(sslcontext, hostnameVerifier))
.build();
Remove SSLv2ClientHello from the SSLContext's enabled protocols.
We have a CXF (2.7.X) client (see code below) in a Java 1.6.0_45 application.
The CXF client calls a Soap WS through a proxy server.
Despite all our efforts, that CXF client performs some requests directly to the WS bypassing the proxy.
The only solution for the moment is to force proxy on the JVM options.
But this solution is not acceptable.
Is there a pb in our code ?
I have not found any clue on the internet or on the CXF jira .
// work only if i define proxy on jvm
/*
System.setProperty("http.proxyHost","87.65.43.21");
System.setProperty("http.proxyPort", "808");
System.setProperty("https.proxyHost", "87.65.43.21");
System.setProperty("https.proxyPort", "808");
*/
// initialize ws
URL wsdlLocation = new URL("https://12.34.56.78:8443/mockHelloWorldSoapBinding?WSDL");
QName qName = new QName("http://my.webservice.com", "HelloWorldService");
HelloWorldService helloWorldService = new HelloWorldService(wsdlLocation, qName);
HelloWorld port = helloWorldService.getHelloWorld();
HTTPConduit httpConduit = (HTTPConduit) ClientProxy.getClient(port).getConduit();
// add proxy parameters
HTTPClientPolicy policy = new HTTPClientPolicy();
policy.setProxyServer("87.65.43.21");
policy.setProxyServerPort(808);
policy.setAllowChunking(false);
httpConduit.setClient(policy);
// call ws
String response = port.sayHello("world");
Hi I have a problem with change ReceiveTimeout, and setup new endpoint
I have a code:
to change the endpoint I'm using code:
Map<String, Object> prop = ((BindingProvider) port).getRequestContext();
prop.put(BindingProvider.ENDPOINT_ADDRESS_PROPERTY, endpoint);
and change timeout :
Client client = ClientProxy.getClient(port);
HTTPConduit http = (HTTPConduit) client.getConduit();
HTTPClientPolicy httpClientPolicy = http.getClient();
httpClientPolicy.setReceiveTimeout(5000);
but this is doesn't work
the last part is setup ReceiveTimeout but for default endpoit.
I use server jboss 6.1
How to change ReceiveTimeout for new endpoint ??