Server http2 settings - okhttp

I want to get the initial HTTP2 setting that the server sent for HTTP/2 connection using okhttp 5.0.0-alpha.10 library
SSLSocketFactory factory = okHttpClient.sslSocketFactory();
SSLSocket socket = (SSLSocket)factory.createSocket("app.test.com", 443);
Http2Connection connection = new Http2Connection.Builder(true, TaskRunner.INSTANCE)
.socket(socket)
.build();
connection.start();
getInitialWindowSize ??
getMaxConcurrentStreams() ??

None of the code in the okhttp3.internal package is intended for end-users to use, including the Http2Connection class.

Related

WebSocketStompClient stompSession future timingout

I'm trying to connect to a Secure WebSocket service using WebSocketStompClient in a Spring Boot application, but it never get past StompSession Future get call (timing out).
I've verified this service works by using 'Smart Websocket Client' Chrome browser extension, but haven't been able to get it working with the Spring Boot client.
I'm unable to figure out what else I can do to further debug this. Not sure if this is a certificate issue or something else.
Any suggestion ?
Update: I even got this working with Java/Kotlin using 'org.java-websocket:Java-WebSocket:1.5.1'. It was just a one liner: connect with the same URI. I think this rules out any potential issue with the certificate.
val URL = "wss://service.foo/bar"
val countDownLatch = CountDownLatch(1)
val client = StandardWebSocketClient()
val stompClient = WebSocketStompClient(client)
stompClient.messageConverter = MappingJackson2MessageConverter()
val sessionHandler = MyEventSocketHandler()
val stompSessionFuture = stompClient.connect(URL, sessionHandler)
// MyEventSocketHandler::afterConnected() never got called. Doing this to figure out what is going on.
val stompSession = stompSessionFuture.get(10, TimeUnit.SECONDS)
countDownLatch.await()

Error during https call through proxy using CXF

In camel-cxf I have to call a SOAP webservice (exposed in https) through a proxy: configuring the http conduit as follows
public void configureClient(Client client) {
String proxySrv = Util.getProperty(Constants.Config.PROXY_SRV);
int proxyPort = new Integer(Util.getProperty(Constants.Config.PROXY_PORT));
log.info("Configurazione del server proxy:'"+proxySrv+"' port:'"+proxyPort+"'");
HTTPConduit conduit = (HTTPConduit) client.getConduit();
HTTPClientPolicy policy = new HTTPClientPolicy();
policy.setProxyServer(proxySrv); // set proxy host
policy.setProxyServerPort(proxyPort); // set proxy port
policy.setProxyServerType(ProxyServerType.SOCKS);
conduit.setClient(policy);
conduit.setAuthSupplier(new DefaultBasicAuthSupplier());
boolean proxyAuthEnabled = new Boolean(Util.getProperty(Constants.Config.PROXY_AUTH_EN));
String user = Util.getProperty(Constants.Config.PROXY_USER);
String pass = Util.getProperty(Constants.Config.PROXY_PASS);
log.info("Recuperati username:'+"+user+"' e password per il proxy:'"+proxySrv+"' port:'"+proxyPort+"'");
if (proxyAuthEnabled) {
ProxyAuthorizationPolicy ap = new ProxyAuthorizationPolicy();
ap.setUserName(user);
ap.setPassword(pass);
conduit.setProxyAuthorization(ap);
// conduit.getAuthorization().setUserName(user);
// conduit.getAuthorization().setPassword(pass);
log.info("Autenticazione abilitata per userName ='"+user+"' per il proxy:'"+proxySrv+"' port:'"+proxyPort+"'");
}
it works for http call (without the proxy server type set) but it doesn't work for https call. This proxy requires basic auth.
Reading various articles I saw that there is a bug in CXF that doesn't send the header authorization in the CONNECT call (and infact I'm getting 407 Authorization required -> even if with the same credentials with http calls it works).
Is there a way to fix it? I read about Olivier Billard solution
https://www.mail-archive.com/users#cxf.apache.org/msg06422.html
but I didn't undestand that solution (and I can't import at code any keystore).
Thanks
Hello I just faced this issue with the apache cxf client, the workaround suggested in the mailing list is to use the following static method of the java.net.Authenticator class :
Authenticator.setDefault(new Authenticator() {
#Override
protected PasswordAuthentication getPasswordAuthentication() {
return new PasswordAuthentication("youruser", "yourpassword".toCharArray());
}
});
This way the basic will be set automatically on all your HttpUrlConnection that uses the proxy, since java 8 you also have to enable basic authentication for HTTPS tunneling, you can do this with the following property:
-Djdk.http.auth.tunneling.disabledSchemes=""
I hope this helps

Websocket connection. Why are we making a call to ws://echo.websocket.org?

I am writing some websocket code and I have this so far:
window.onload = function() {
// Get references to elements on the page.
var form = document.getElementById('message-form');
var messageField = document.getElementById('message');
var messagesList = document.getElementById('messages');
var socketStatus = document.getElementById('status');
var closeBtn = document.getElementById('close');
var socket = new WebSocket('ws://echo.websocket.org');
// Show a connected message when the WebSocket is opened.
socket.onopen = function(event) {
socketStatus.innerHTML = 'Connected to: ' + event.currentTarget.url;
socketStatus.className = 'open';
};
// Handle any errors that occur.
socket.onerror = function(error) {
console.log('WebSocket Error: ' + error);
};
form.onsubmit = function(e) {
e.preventDefault();
// Retrieve the message from the textarea.
var message = messageField.value;
// Send the message through the WebSocket.
socket.send(message);
// Add the message to the messages list.
messagesList.innerHTML += '<li class="sent"><span>Sent:</span>' + message +
'</li>';
// Clear out the message field.
messageField.value = '';
return false;
};
socket.onmessage = function(event) {
var message = event.data;
messagesList.innerHTML += '<li class="received"><span>Received:</span>' +
message + '</li>';
};
closeBtn.onclick = function(e) {
e.preventDefault();
// Close the WebSocket.
socket.close();
return false;
};
socket.onclose = function(event) {
socketStatus.innerHTML = 'Disconnected from WebSocket.';
socketStatus.className = 'closed';
};
};
What is this code doing:
var socket = new WebSocket('ws://echo.websocket.org');
What url is that? When I visit there with my browser it does not exist but it seems to be important as I can't simply jus replace that url with random strings. What does it do? Is Websocket an external API?
I'm looking at the network tab and I see this:
Request URL: ws://echo.websocket.org/
Request Method: GET
Status Code: 101 Web Socket Protocol Handshake
conceptually, what is going on? Why do I need to make a request to an external site to use Websockets?
echo.websocket.org provides a webSocket server that lets you make a webSocket connection to it and then it simply echos back to you anything that you send it. It's there primarily for testing and demo purposes.
The code you show looks like a demo/testing app designed to run in a browser web page for a webSocket connection which you can access something similar here: https://websocket.org/echo.html.
A URL starting with ws:// indicates a connection that intends to use the webSocket protocol.
What is this code doing:
var socket = new WebSocket('ws://echo.websocket.org');
It is making a webSocket connection to a webSocket server at echo.websocket.org.
What url is that?
That is a webSocket URL that indicates the intent to use the webSocket protocol to connect and talk to that host. This is not something you type in the URL bar of a browser. It's something that is used by a programming language (such as Javascript in your browser).
Is Websocket an external API?
It's a protocol that specifies a means of connecting, a security scheme, a packet data format, etc... You could say that the http protocol is to the webSocket protocol as the English language is to Japanese. They are different means of communicating. The specification for the webSocket protocol is here: https://www.rfc-editor.org/rfc/rfc6455.
It's also designed to fit well into the http/browser world and to be friendly with infrastructure that was originally designed for http requests. Just searching for "what is websocket" on Google will turn up all sorts of descriptive articles. The Wikipedia page for webSocket provides a pretty good overview.
There is tons written on the web about what the webSocket protocol is and is useful for so I won't repeat that here. You can see a tutorial on webSocket clients here and a tutorial on webSocket servers here.
In a nutshell, it's designed to be a long lasting, continuous connection (supported in all modern browsers) that allows a client to connect to a server and then maintain a continuous connection for (potentially) a long duration. While that connection is open, data can be easily sent both ways over the webSocket. The primary reason people use it is when they want the server to be able to send data directly to the client in a timely fashion without making the client continuously ask the server over and over again if it has any new data. Once a webSocket connection is established, the server can just "push" data to the client at any time.
I'm looking at the network tab and I see this. Conceptually, what is going on?
Request URL: ws://echo.websocket.org/
Request Method: GET Status Code:
101 Web Socket Protocol Handshake
Those are the first steps of establishing a webSocket connection. You can see a more complete description of how that connection works here: How socket.io works. That post talks about socket.io which is another layer built on top of webSocket, but the underlying protocol is webSocket.
Why do I need to make a request to an external site to use Websockets?
A webSocket's purpose is to connect a client to a server (so data can then be sent between them) so it would only be used when connecting to some server somewhere.

IBM Watson Conversation Service Using Proxy settings from Java API

I have developed a conversation service using IBM Watson and deployed. I am able to access my service using the IBM Watson API explorer. I tried connecting the service using a Java API as explained in https://developer.ibm.com/recipes/tutorials/integration-of-ibm-watson-conversation-service-to-your-java-application/ I am working on a corporate network, so using proxy to access internet. Now I am not able to access the service from my Java API. I am getting below error.
Exception in thread "main" java.lang.RuntimeException: java.net.ConnectException: Failed to connect to gateway.watsonplatform.net/169.48.66.222:443
at com.ibm.watson.developer_cloud.service.WatsonService$1.execute(WatsonService.java:182)
at com.chat.CustomerChat.conversationAPI(CustomerChat.java:47)
at com.chat.CustomerChat.main(CustomerChat.java:32)
Caused by: java.net.ConnectException: Failed to connect to gateway.watsonplatform.net/169.48.66.222:443
at okhttp3.internal.io.RealConnection.connectSocket(RealConnection.java:187)
at okhttp3.internal.io.RealConnection.buildConnection(RealConnection.java:170)
at okhttp3.internal.io.RealConnection.connect(RealConnection.java:111)
at okhttp3.internal.http.StreamAllocation.findConnection(StreamAllocation.java:187)
at okhttp3.internal.http.StreamAllocation.findHealthyConnection(StreamAllocation.java:123)
at okhttp3.internal.http.StreamAllocation.newStream(StreamAllocation.java:93)
at okhttp3.internal.http.HttpEngine.connect(HttpEngine.java:296)
at okhttp3.internal.http.HttpEngine.sendRequest(HttpEngine.java:248)
at okhttp3.RealCall.getResponse(RealCall.java:243)
at okhttp3.RealCall$ApplicationInterceptorChain.proceed(RealCall.java:201)
at okhttp3.RealCall.getResponseWithInterceptorChain(RealCall.java:163)
at okhttp3.RealCall.execute(RealCall.java:57)
How do we set proxy connection in IBM watson Connection service?
My code:(Modified the user credentials and workspace id here)
ConversationService service = new ConversationService("2017-05-26");
service.setUsernameAndPassword("dfgdfg-578a-46b6-55hgg-ghgg4343", "ssdsd455gfg");
MessageRequest newMessage = new MessageRequest.Builder().inputText(input).context(context).build();
String workspaceId = "fgfdgfgg-ce7a-422b-af23-gfgf56565";
MessageResponse response = service.message(workspaceId, newMessage).execute();
Not completely sure about work around for Java, but when i had similar issue with Node, i had to set up proxy variables and that helped. I would recommend you to give a try by setting up proxy variables in eclipse and JVM. And also i think this Java file must be helpful.
After going though IBM API documentation I found below method to set the proxy. It should work.
HttpConfigOptions config = new HttpConfigOptions
.Builder()
.proxy(new Proxy(Proxy.Type.HTTP,
new InetSocketAddress("<Proxy IP>", <Proxy Port>)))
.build();
service.configureClient(config);
I implemented this code with Java-sdk 6.14.0. IBM has discontinued ConversationService package and deprecated Conversation package in this version of SDK. Instead Assistant package has been introduced. My working code is as below.
Assistant service = null;
Context context = null;
if (watsonUser.equalsIgnoreCase(APIKEY_AS_USERNAME))
{
IamOptions iamOptions = new IamOptions.Builder().apiKey(watsonApikey).build();
service = new Assistant(watsonVersion, iamOptions);
}
else
{
service = new Assistant(watsonVersion, watsonUser,watsonPassword);
}
service.setEndPoint(watsonUrl);
if(watsonProxy != null)
{
HttpConfigOptions config = new HttpConfigOptions
.Builder()
.proxy(new Proxy(Proxy.Type.HTTP,
new InetSocketAddress(watsonProxyIP, watsonProxyPort)))
.build();
service.configureClient(config);
}
String workspaceId = watsonWorkspace_id;
InputData input = new InputData.Builder(inputStr).build();
MessageOptions options = new MessageOptions.Builder(workspaceId)
.context(context)
.input(input)
.build();
MessageResponse response = service.message(options).execute();
context = response.getContext();
I have checked the code with Conversation package based implementation. It worked. I couldn't checked with code given in the question as ConversationService package is no more in the current SDK.

spring websockets using stomp and sockjs create new connection on opening new tab

I am using spring websockets using stomp and sockjs without spring security . When I have one my app in a browser, then new socket connection established, but when I open another tab in same browser, it also create new socket connection.So i want to stop this behaviour and want it to use the same connection id to on opening new tab.Its a chat app.Using code from this blog:
https://github.com/salmar/spring-websocket-chat
can anyone give me working code how to store connection in localstorage n retrieve the stored socket connection in new tab from localstorage?
function connect() {
var socket = new SockJS('/spring-mvc-java/chat');
stompClient = Stomp.over(socket);
stompClient.connect({}, function(frame) {
console.log('Connected: ' + frame);
stompClient.subscribe('/topic/messages', function(messageOutput) {
showMessageOutput(JSON.parse(messageOutput.body));
});
});
}
Local storage in window is the simplest solution to above problem. Store the session id in local storage object and you can access across other tabs.Retrieve the session id from the object and reuse for the connection.
Example:
localStorage.setItem('sessionId', '123abc');
Retrieve the same object in other tab with:
localStorage.getItem("sessionId");
You can refer to below link on how to use localStorage:
https://developer.mozilla.org/en/docs/Web/API/Window/localStorage

Resources