How to add HTTP proxy to JAX-WS? - java

I have a WSDL file which I've turned into Java code by using WSDL2Java inside SoapUI, it works fine, but now I need to add my company's proxy to it, so every SOAP http request would go through it (but not other http requests).
I've looked through multiple threads concerning the same issue and found these options:
system wide proxy by adding
System.getProperties().put("proxySet", "true");
System.getProperties().put("https.proxyHost", "10.10.10.10");
System.getProperties().put("https.proxyPort", "8080");
which doesn't work for me, since it affect the whole jvm.
adding the following code
HelloService hello = new HelloService();
HelloPortType helloPort = cliente.getHelloPort();
org.apache.cxf.endpoint.Client client = ClientProxy.getClient(helloPort);
HTTPConduit http = (HTTPConduit) client.getConduit();
http.getClient().setProxyServer("proxy");
http.getClient().setProxyServerPort(8080);
http.getProxyAuthorization().setUserName("user proxy");
http.getProxyAuthorization().setPassword("password proxy");
which I don't get how to use. My generated code doesn't have any traces of org.apache.cxf, only javax.xml.ws.
Adding this to my port configuration:
((BindingProvider) port).getRequestContext().put("http.proxyHost", "proxy#example.com");
((BindingProvider) port).getRequestContext().put("http.proxyPort", "80");
Here I use a random non-existing proxy and expect to get an error of any sort(timeout, invalid proxy, etc.), but instead it goes through without any errors.

Here is an example without using 3rd party libraries.
https://github.com/schuch/jaxws-proxy-example/blob/master/jaxws-client-with-proxy/src/main/java/ch/schu/example/helloworld/Client.java
package ch.schu.example.helloworld;
import java.net.ProxySelector;
import ch.schu.example.hello.HelloImpl;
import ch.schu.example.hello.HelloImplService;
public class Client {
public static void main(String[] args) {
ProxySelector.setDefault(new MyProxySelector());
HelloImplService service = new HelloImplService();
HelloImpl hello = service.getHelloImplPort();
System.out.println(hello.sayHello("Howard Wollowitz"));
}
}
https://github.com/schuch/jaxws-proxy-example/blob/master/jaxws-client-with-proxy/src/main/java/ch/schu/example/helloworld/MyProxySelector.java
package ch.schu.example.helloworld;
import java.io.IOException;
import java.net.InetSocketAddress;
import java.net.*;
import java.util.*;
public class MyProxySelector extends ProxySelector {
#Override
public List<Proxy> select(URI uri)
{
System.out.println("select for " + uri.toString());
Proxy proxy = new Proxy(Proxy.Type.HTTP, new InetSocketAddress("localhost", 9999));
ArrayList<Proxy> list = new ArrayList<Proxy>();
list.add(proxy);
return list;
}
#Override
public void connectFailed(URI uri, SocketAddress sa, IOException ioe) {
System.err.println("Connection to " + uri + " failed.");
}
}

Related

Jetty 9 WebSocket client issue when using secure connection

I'm writing a WebSocket client in a java application, using the Jetty 9.4.18 libraries.
I'm pretty new to WebSockets, so I started testing using the two sample classes from the Jetty documentation, connecting to echo.websocket.org
The test runs fine when I connect without SSL, but if fails when the connection is done to wss://echo.websocket.org
I always get the same exception:
java.io.EOFException: HttpConnectionOverHTTP#50371e9d::DecryptedEndPoint#6dc65fc2{echo.websocket.org/174.129.224.73:443<->/192.168.1.34:60521,OPEN,fill=-,flush=C,to=226/0}
at org.eclipse.jetty.client.http.HttpReceiverOverHTTP.earlyEOF(HttpReceiverOverHTTP.java:338)
at org.eclipse.jetty.http.HttpParser.parseNext(HttpParser.java:1551)
at org.eclipse.jetty.client.http.HttpReceiverOverHTTP.shutdown(HttpReceiverOverHTTP.java:209)
at org.eclipse.jetty.client.http.HttpReceiverOverHTTP.process(HttpReceiverOverHTTP.java:147)
at org.eclipse.jetty.client.http.HttpReceiverOverHTTP.receive(HttpReceiverOverHTTP.java:73)
at org.eclipse.jetty.client.http.HttpChannelOverHTTP.receive(HttpChannelOverHTTP.java:133)
at org.eclipse.jetty.client.http.HttpConnectionOverHTTP.onFillable(HttpConnectionOverHTTP.java:155)
at org.eclipse.jetty.io.AbstractConnection$ReadCallback.succeeded(AbstractConnection.java:305)
at org.eclipse.jetty.io.FillInterest.fillable(FillInterest.java:103)
at org.eclipse.jetty.io.ssl.SslConnection$DecryptedEndPoint.onFillable(SslConnection.java:411)
at org.eclipse.jetty.io.ssl.SslConnection.onFillable(SslConnection.java:305)
at org.eclipse.jetty.io.ssl.SslConnection$2.succeeded(SslConnection.java:159)
at org.eclipse.jetty.io.FillInterest.fillable(FillInterest.java:103)
at org.eclipse.jetty.io.ChannelEndPoint$2.run(ChannelEndPoint.java:118)
at org.eclipse.jetty.util.thread.QueuedThreadPool.runJob(QueuedThreadPool.java:765)
at org.eclipse.jetty.util.thread.QueuedThreadPool$2.run(QueuedThreadPool.java:683)
at java.lang.Thread.run(Thread.java:748)
It looks like the server closes without answering to the handshake request.
I am aware of SslContextFactory, but my understanding is that it should be used only if you need your own TrustStore or KeyStore, or for other special cases.
Note also that after some failed attempt I downloaded another websocket implementation from https://github.com/TooTallNate/Java-WebSocket, and it works fine with both ws and wss, without setting anything specific for SSL.
However for this project I'm bind to use Jetty.
The code I'm using is exactly the sample from Jetty documentation at https://www.eclipse.org/jetty/documentation/9.4.x/jetty-websocket-client-api.html
the only change I did was to add an onError method to SimpleEchoSocket, that dumps the full exception stack.
Am I missing something?
Thanks in advance!
Unfortunately, websocket.org (and Kaazing host/proxy) has a bunch of TLS issues at this point in time, so using their public servers are not sane choice right now.
Here's a different demo, also using TLS and WebSocket, against a stackexchange server with a proper and sane TLS/SSL implementation.
This was written against Jetty 9.4.18.v20190429
package org.eclipse.jetty.demo;
import java.net.URI;
import java.util.concurrent.Future;
import org.eclipse.jetty.client.HttpClient;
import org.eclipse.jetty.util.component.LifeCycle;
import org.eclipse.jetty.util.log.Log;
import org.eclipse.jetty.util.log.Logger;
import org.eclipse.jetty.util.ssl.SslContextFactory;
import org.eclipse.jetty.websocket.api.Session;
import org.eclipse.jetty.websocket.api.annotations.OnWebSocketClose;
import org.eclipse.jetty.websocket.api.annotations.OnWebSocketConnect;
import org.eclipse.jetty.websocket.api.annotations.OnWebSocketError;
import org.eclipse.jetty.websocket.api.annotations.OnWebSocketMessage;
import org.eclipse.jetty.websocket.api.annotations.WebSocket;
import org.eclipse.jetty.websocket.client.WebSocketClient;
#WebSocket
public class SecureClientSocket
{
private static final Logger LOG = Log.getLogger(SecureClientSocket.class);
public static void main(String[] args)
{
String url = "wss://qa.sockets.stackexchange.com/";
SslContextFactory ssl = new SslContextFactory.Client();
ssl.setEndpointIdentificationAlgorithm("HTTPS");
HttpClient http = new HttpClient(ssl);
WebSocketClient client = new WebSocketClient(http);
try
{
http.start();
client.start();
SecureClientSocket socket = new SecureClientSocket();
Future<Session> fut = client.connect(socket, URI.create(url));
Session session = fut.get();
session.getRemote().sendString("Hello");
session.getRemote().sendString("155-questions-active");
}
catch (Throwable t)
{
LOG.warn(t);
}
finally
{
stop(http);
stop(client);
}
}
private static void stop(LifeCycle lifeCycle)
{
try
{
lifeCycle.stop();
}
catch (Exception e)
{
e.printStackTrace();
}
}
#OnWebSocketConnect
public void onConnect(Session sess)
{
LOG.info("onConnect({})", sess);
}
#OnWebSocketClose
public void onClose(int statusCode, String reason)
{
LOG.info("onClose({}, {})", statusCode, reason);
}
#OnWebSocketError
public void onError(Throwable cause)
{
LOG.warn(cause);
}
#OnWebSocketMessage
public void onMessage(String msg)
{
LOG.info("onMessage() - {}", msg);
}
}

How to set the HTTP-Session-Timeout in Jetty 9 (embedded)?

I would like to use Jetty 9 (v9.2.12.v20150709) embedded for my test cases.
But I am unable to change the HTTP-Session-Timeout programmatically.
This call webapp.getSessionHandler().getSessionManager().setMaxInactiveInterval(timeoutInSeconds); doesn't seem to work.
Here is reduced code segement, which shows what I do:
import java.io.IOException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.eclipse.jetty.client.HttpClient;
import org.eclipse.jetty.client.api.ContentResponse;
import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.webapp.WebAppContext;
#SuppressWarnings("javadoc")
public class EmbeddedJetty
{
#SuppressWarnings("serial")
public static class TimeoutServlet extends HttpServlet
{
#Override
protected void doGet(HttpServletRequest request,
HttpServletResponse response) throws IOException
{
// return the value of the currently used HTTP-Session Timeout
response.setContentType("text/html");
response.setStatus(HttpServletResponse.SC_OK);
response.getWriter().println("<h1>Timeout: " + request.getSession()
.getMaxInactiveInterval() + "</h1>");
}
}
public static void main(String[] args) throws Exception
{
// the custom timeout, which I am trying to set
int timeoutInSeconds = 1234;
Server server = new Server(0);
WebAppContext webapp = new WebAppContext();
webapp.setContextPath("/");
webapp.setResourceBase(System.getProperty("user.dir"));
// Can't set custom timeout. Following Statement doesn't work.
webapp.getSessionHandler().getSessionManager().setMaxInactiveInterval(
timeoutInSeconds);
server.setHandler(webapp);
webapp.addServlet(TimeoutServlet.class.getName(), "/*");
server.start();
// get current URL of the server
String url = server.getURI().toString();
System.out.println("\n URL: " + url);
// server.dumpStdErr();
// make a request to get the used timeout setting
HttpClient httpClient = new HttpClient();
httpClient.start();
ContentResponse response = httpClient.GET(url);
httpClient.stop();
String timeoutInfo = response.getContentAsString();
System.out.println(timeoutInfo);
// check if the custom timeout is used
if( timeoutInfo.contains(String.valueOf(timeoutInSeconds)) )
{
System.out.println("Custom Timeout is used.");
}
else
{
// Unfortunately, I get the default(?) everytime
System.out.println("Default Timeout? Custom Value is NOT used.");
}
System.out.println("Press Enter to exit ...");
System.in.read();
server.stop();
server.join();
}
}
I am using the WebAppContext-Style of setup, because this allowed me to get my ServletContextListeners to work by using WebAppContext.addEventListener(). Which I couldn't get to work by using a ServletHandler.
Also I am using the Version 9.2.12.v20150709 of Jetty, because it is Classpath-compatible with Selenium v2.5.2 (which supports Java 7 (project requirement)).
Have you any suggestions, what i am doing wrong?
Thank you for your time.
A WebAppContext has some defaults, which are loaded during server.start() (WebAppContext.startContext()).
These defaults contain also a DefaultWebDescriptor located in the jetty-webapp.jar under /org/eclipse/jetty/webapp/webdefault.xml. This Descriptor includes a session-config, which sets the timeout to the default of 30m (1800s).
To overwrite the defaults the call of setMaxInactiveInterval() must be done after the server is started:
server.start();
webapp.getSessionHandler().getSessionManager().setMaxInactiveInterval(timeoutInSeconds);
Or to avoid these defaults, it might be better to use a ServletContextHandler instead.

How to set source IP to http request?

I need to set source IP address (for something like IP Spoofing) before sending out an http request. Class used for setting up http connection is HTTPURLConnection. I found below link on stackoverflow which is really useful.
Registering and using a custom java.net.URL protocol
As in the post, I have already created 3 classes extending URLConnection , URLStreamHandler and implementing URLStreamHandlerFactory. This looks to be working fine; however I am getting exception which I think is because I have not implemented getInputStream for URLConnection as was mentioned in above post.
I have couple of questions
1> I am extending custom URLConnection class from HTTPURLConnection, so what's the need of implementing getInputStream as anyway it's a virtual method
2> If I have to do it, can someone provide sample implementation of this method?
JMeter already provides the IP Spoofing feature.
In Http Request Defaults, select (in version 3.0 of JMeter) advanced tab :
See http://jmeter.apache.org/usermanual/component_reference.html#HTTP_Request_parms1:
Source address field
[Only for HTTP Request with HTTPClient implementation]
This property is used to enable IP Spoofing. It overrides the default local IP address for this sample. The JMeter host must have multiple IP addresses (i.e. IP aliases, network interfaces, devices). The value can be a host name, IP address, or a network interface device such as "eth0" or "lo" or "wlan0".
If the property httpclient.localaddress is defined, that is used for all HttpClient requests.
Based on UBIK LOAD PACK's answer. Here is the same code using Aapche http client 3.x. (The variable for setting source IP is args[1])
import org.apache.commons.httpclient.*;
import org.apache.commons.httpclient.methods.*;
import org.apache.commons.httpclient.protocol.Protocol;
public class HC3Test {
public static void main(String[] args) throws Exception {
String url = args[0];
java.net.URL uri = new java.net.URL(url);
HostConfiguration hc = new HostConfiguration();
hc.setHost(uri.getHost(), uri.getPort(), Protocol.getProtocol(uri.getProtocol()));
hc.setLocalAddress(java.net.InetAddress.getByName(args[1]));//for pseudo 'ip spoofing'
HttpClient client = new HttpClient(new SimpleHttpConnectionManager());
client.setHostConfiguration(hc);
GetMethod method = new GetMethod(url);
client.executeMethod(method);
method.releaseConnection();
}
}
Sample code for http client 4.x:
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.conn.params.ConnRoutePNames;
public class HC4Test {
public static void main(String[] args) throws Exception {
DefaultHttpClient httpClient = new DefaultHttpClient();
org.apache.http.params.HttpParams params = httpClient.getParams();
params.setParameter(ConnRoutePNames.LOCAL_ADDRESS,
java.net.InetAddress.getByName(args[1]));//for pseudo 'ip spoofing'
httpClient.execute(new HttpGet(args[0]));
}
}
To accomplish to have a different source address via an http request you could use a local proxy.
import java.io.IOException;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.MalformedURLException;
import java.net.Proxy;
import java.net.URL;
import java.net.URLConnection;
import java.net.UnknownHostException;
public class Huhu {
public static void main(String[] args) throws IOException {
URL url = new URL("http://google.com");
Proxy proxy = new Proxy(Proxy.Type.DIRECT,
new InetSocketAddress(
InetAddress.getByAddress(
new byte[]{your, ip, interface, here}), yourTcpPortHere));
URLConnection conn = url.openConnection(proxy);
}
}
You do not have to override anything this way.

Java Rest API client - GET method - Error 415

I am new to writing Java client for Restful API using Apache CXF.
On running below code I am getting error 415 returned which when I looked online shows as "unsupported media type". In order to fix it I changed the code to "target.request(MediaType.APPLICATION_XML)" from original target.request(). However this didn't fix the code.
What is the best way to debug this issue?
Thanks a lot in advance for your time.
Update: After discussion with the Rest API developer I came to know that I need to add a header "("Content-Type", "application/x-www-form-urlencoded");". but I am not sure how to add a header. Does anyone know how to add this header here?
package com.blackhawk.ivr.restAPI.client;
import javax.ws.rs.client.Client;
import javax.ws.rs.client.ClientBuilder;
import javax.ws.rs.client.Invocation;
import javax.ws.rs.client.WebTarget;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
public class BlissRestAPI {
public static final String BLISS_SERVICRE_URL = "http://x.x.x.x:9090/services";
public static void main(String[] args) {
Client client = ClientBuilder.newClient();
WebTarget target = client.target(BLISS_SERVICRE_URL);
target = target.path("/cardmanagementservices/v3/card/status").queryParam("ani", "xxxxxxxxxx").queryParam("card.expiration", "xxxxxx").queryParam("card.number", "xxxxxxxxxxxxxxxx").queryParam("channel.id", "xyz");
Invocation.Builder builder = target.request(MediaType.APPLICATION_XML);
Response response = builder.get();
System.out.println(response.getStatus());
response.close();
client.close();
}
}
First you can change the media type as given below.
Client: MediaType.APPLICATION_XML
Rest: MediaType.APPLICATION_JSON
JAX-WS are Java standard to build web service. So you have used it here, As my knowledge it is easy to use axis 2 to this kind of web services and clients since there are more implementations of JAX-WS. So i will give you a solution using apache axis technology.
import org.apache.axis.client.Call;
import org.apache.axis.client.Service;
import org.apache.axis.encoding.XMLType;
import javax.xml.rpc.ParameterMode;
public class axisClient {
public static void main(String [] args) throws Exception {
String endpoint = "http://localhost:8090/archive_name/service_name.jws";
Service service = new Service();
Call call = (Call) service.createCall();
call.setTargetEndpointAddress( new java.net.URL(endpoint) );
call.setOperationName( "service_method_name" );
call.addParameter("parameter_name", XMLType.XSD_STRING, ParameterMode.IN );
call.setReturnType( XMLType.XSD_STRING );
call.setProperty(Call.CHARACTER_SET_ENCODING, "UTF-8");
String jsonString = (String) call.invoke( new Object [] { "parameter_value"});
System.out.println("Got result : " + jsonString);
}
}
I got it working by using below code (got 200 status returned)
WebClient client = WebClient.create(BLISS_SERVICRE_URL);
client.path("/cardmanagementservices/v3/card/status").query("ani", "xxxxxxxxxx").query("card.expiration", "xxxxxx").query("card.number", "xxxxxxxxxxxxxx").query("channel.id", "xxxxx");
client.type(MediaType.APPLICATION_FORM_URLENCODED).accept(MediaType.APPLICATION_XML);
client.header("Content-Type","application/x-www-form-urlencoded");
Response response = client.get();
System.out.println(response.getStatus());

Checking the type of a web proxy

How do I determine whether a web proxy IP is of type HTTP or SOCKS4/5 with java?
Thank you.
As mentioned in the comments from my other answer, if you know the IP address of a proxy server and want to detect what type it is, you could try each proxy type in Java until one works.
import java.io.IOException;
import java.net.InetSocketAddress;
import java.net.Proxy;
import java.net.SocketException;
import java.net.URL;
import java.net.URLConnection;
import java.util.Arrays;
import java.util.List;
public class ProxyTest
{
public static void main(String... args)
throws IOException
{
InetSocketAddress proxyAddress = new InetSocketAddress("myproxyaddress", 1234);
Proxy.Type proxyType = detectProxyType(proxyAddress);
System.out.println(proxyAddress + " is a " + proxyType + " proxy.");
}
public static Proxy.Type detectProxyType(InetSocketAddress proxyAddress)
throws IOException
{
URL url = new URL("http://www.google.com");
List<Proxy.Type> proxyTypesToTry = Arrays.asList(Proxy.Type.SOCKS, Proxy.Type.HTTP);
for (Proxy.Type proxyType : proxyTypesToTry)
{
Proxy proxy = new Proxy(proxyType, proxyAddress);
//Try with SOCKS
URLConnection connection = null;
try
{
connection = url.openConnection(proxy);
//Can modify timeouts if default timeout is taking too long
//connection.setConnectTimeout(1000);
//connection.setReadTimeout(1000);
connection.getContent();
//If we get here we made a successful connection
return(proxyType);
}
catch (SocketException e) //or possibly more generic IOException?
{
//Proxy connection failed
}
}
//No proxies worked if we get here
return(null);
}
}
In this code, it first tries to connect to www.google.com using the proxy at myproxyaddress with SOCKS, and if that fails it will try using it as an HTTP proxy, returning the method that worked, or null if none worked.
If you want to determine the type of proxy being used from Java, you can use ProxySelector and Proxy.
e.g.
import java.net.Proxy;
import java.net.ProxySelector;
import java.net.URI;
import java.util.List;
public class ProxyTest
{
public static void main(String... args)
{
System.setProperty("java.net.useSystemProxies", "true");
List<Proxy> proxyList = ProxySelector.getDefault().select(URI.create("http://www.google.com"));
if (!proxyList.isEmpty())
{
Proxy proxy = proxyList.get(0);
switch (proxy.type())
{
case DIRECT:
System.out.println("Direct connection - no proxy.");
break;
case HTTP:
System.out.println("HTTP proxy: " + proxy.address());
break;
case SOCKS:
System.out.println("SOCKS proxy: " + proxy.address());
break;
}
}
}
}

Categories