HTTP/2 with OkHttp - okhttp

I am trying to communicate with a HTTP/2 server using OkHttp client.
Added to Maven POM:
<dependency>
<groupId>com.squareup.okhttp3</groupId>
<artifactId>okhttp</artifactId>
<version>3.2.0</version>
</dependency>
And this is my test code:
OkHttpClient client = new OkHttpClient();
Request request = new Request.Builder().url("https://http2.akamai.com/demo").build();
Response response = client.newCall(request).execute();
System.out.println("Protocol: " + response.protocol());
System.out.println(response.body().string());
But when I run it it prints:
Protocol: http/1.1
and
This browser is not HTTP/2 enabled.
Environment: OpenJDK 8 on Linux.
Do you need something additional? I saw something called "ALPN" but did not quite understand the concept.

ALPN is required for HTTP/2, but it isn’t available in desktop Java until JDK 9. In Java 7 and Java 8 you’ll need a hack called jetty-alpn to enable it.
(For Java 9 there’s ALPN on the platform but only in the upcoming OkHttp 3.3.)

Alternatively, you can use conscrypt with apache, jetty or okhttpclient to get ALPN support in jdk8 itself,
Security.insertProviderAt(Conscrypt.newProvider(), 1);
p.s: use conscrypt-openjdk-uber jar to include all dependencies

Related

ActiveMQ Artemis broker and Spring Boot - prevent from starting embedded

I have a project, where I want to use ActiveMQ Artemis with Spring Boot 3.0.1, but I have an issue with embedded server.
Dependencies used:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-artemis</artifactId>
</dependency>
<dependency>
<groupId>org.apache.activemq</groupId>
<artifactId>artemis-jms-server</artifactId>
</dependency>
The drill should be: when needed, start embedded server, but there is no need for that, connect to existing instance.
From I understand, there are two parameters, that might be useful here:
spring.artemis.mode - I should set it whenever want to start embedded service or connect to native instance of the server and:
spring.artemis.embedded.enabled - Quote from documentation, "Whether to enable embedded mode if the Artemis server APIs are available."
All that said, setting first one to native and second one to false does not do the trick. Native server is still starting. Am I missing something? Is there a simple way to tell Spring Boot via property or any other way to not start server if not needed?
EDIT1:
Maybe I'll provide some more details.
All configuration for the Artemis goes into separate module, where dependencies that has been provided above are.
Then, this module (let's call it "message") has only following properties:
spring:
artemis:
broker-url: tcp://localhost:61616
mode: native
Then, other module has than module as a dependency (has changed names of the groupId and artifactId for simplicity):
<dependency>
<groupId>org.example.company</groupId>
<artifactId>message</artifactId>
</dependency>
Then, changing the value in the properties does nothing to starting the server, in both configurations I see in logs:
2023-01-23T11:41:18.445+01:00 INFO 35336 --- [ restartedMain] o.apache.activemq.artemis.core.server : AMQ221000: live Message Broker is starting with configuration Broker Configuration (clustered=false,journalDirectory=C:\Users\USR~1.JAR\AppData\Local\Temp\artemis-data/journal,bindingsDirectory=data/bindings,largeMessagesDirectory=data/largemessages,pagingDirectory=data/paging)
...
2023-01-23T11:41:19.058+01:00 INFO 35336 --- [ restartedMain] o.apache.activemq.artemis.core.server : AMQ221007: Server is now live
2023-01-23T11:41:19.059+01:00 INFO 35336 --- [ restartedMain] o.apache.activemq.artemis.core.server : AMQ221001: Apache ActiveMQ Artemis Message Broker version 2.26.0 [localhost, nodeID=78075d71-9b0a-11ed-8116-3cf011ac7196]
In this second module, where "message" is being imported as a dependency, I'm sending and receiving some messages, if that matters.

Seeing difference when run jmx from Java application and GUI mode

My Java pom.xml has these dependencies:
<dependency>
<groupId>org.apache.jmeter</groupId>
<artifactId>ApacheJMeter_core</artifactId>
<version>5.0</version>
</dependency>
and in my jmx file -> jsr223 assertion I have this simple function:
log.info(prev.getResponseDataAsString())
When I run from GUI mode I am able to see the complete response logged in the console, but when my Java application executes the same jmx, I got:
2018/10/25 20:50:53,576 12050 [INFO ] [Thread Group 1-1] (?:?) –
${__FileToString(${inputFilePath},,)}
Is this because I miss some dependencies in my pom.xml? Since it always return
${__FileToString(${inputFilePath},,)}
instead of the actual response which cause I am not able to continue the rest of the test. Rest of stuff all depends on this result. This function comes from the body data of the HTTP Request sampler!!!!!! If I give actual body there then I am able to run the jmx...... Any idea how to deal with this dynamic body data?
UPDATE 1
I found the solution! Instead directly use the ${__FileToString(${inputFilePath},,)} in the body data of HTTP Request Sampler, I can just create one more JSR223 Sampler above the HTTP Request Sampler and in this sampler, I can just do:
import org.apache.commons.io.FileUtils
log.info("--------------------------------------- "+ '${inputFilePath}')
String content = FileUtils.readFileToString(new File('${inputFilePath}'))
vars.put("reqBody", content)
and in the body data of HTTP Request Sampler, I will do ${reqBody}. That's it!
You were missing dependency :
<dependency>
<groupId>org.apache.jmeter</groupId>
<artifactId>ApacheJMeter_functions</artifactId>
<version>5.0</version>
</dependency>

Puppet Jruby NetHttp get request seems to have bad ciphers

We wrote a puppet function which needs to do a http get request over tls to a server. The http request is done directly from the puppet master. The remote server needs apparently more recents ciphers than provided by our function (we use the ruby Net/Http library). Consequently, the remote server immedialty close the connection (Client Hello, [ACK], [FIN, ACK] )
def http_client
uri = URI("https://#{#config['server']}")
http = Net::HTTP.new(uri.host, uri.port)
http.use_ssl = true
http.verify_mode = OpenSSL::SSL::VERIFY_NONE unless #config['vmssc_tls_verify']
http
end
We tried to CuRL the same API from the puppet master, with success, it appears the openssl version used by CuRL is different than the one used by puppet.
The difference we found was that in curl we had like 32 ciphers in SHA256 but with the Net/Http library used by puppet we only had 11 ciphers in SHA1.
Puppet server is running with jruby, so we tried to add java cryptography extension in openJDK but without success.
We also observe that the ciphers listed in the /etc/puppetlabs/puppetserver/conf.d/puppetserver.conf file are not honored (hence we got the list of the ciphers used by the client in our tcpdump) :
# settings related to HTTP client requests made by Puppet Server
http-client: {
# A list of acceptable protocols for making HTTP requests
ssl-protocols: [
TLSv1.2,
]
# A list of acceptable cipher suites for making HTTP requests
cipher-suites: [
TLS_RSA_WITH_AES_256_CBC_SHA256,
TLS_RSA_WITH_AES_256_CBC_SHA,
TLS_RSA_WITH_AES_128_CBC_SHA256,
TLS_RSA_WITH_AES_128_CBC_SHA,
]
We tried to upgrade the version of openJDK to an oracle JDK but without success.
We're running on a puppetserver version 2.7.0 with Jruby and openJDK 8 with a TLS_Version 1.2.
Also when the puppetserver is started in native ruby everything works fine, we've got the goods ciphers. We don't want to stay with that configuration for the performance issue.

Jersey 2.7 tracing on Glassfish 4.1.1 doesn't work

I tried following the instructions located here: https://jersey.java.net/documentation/latest/monitoring_tracing.html#tracing
and it just doesn't work. I get nothing.
Glassfish JVM Options: -Djersey.config.server.tracing.type=ON_DEMAND
Advance REST Client Headers: X-Jersey-Tracing-Accept: whatever
X-Jersey-Tracing-Threshold: VERBOSE Content-Type:
application/x-jersey-test OR Content-Type: application/json
NOTE: Equivalent curl call doesn't either
So, how do I get Jersey tracing working?

HTTP2_Plain in node-http2 module is not working?

I want to create a http2 server using node-http2 module without TLS. My code is as follows:
http2 = require('http2');
const bunyan = require('bunyan');
var log = bunyan.createLogger({name: "HTTP2 server without TLS!"});
var options = {
log: log
}
var server = http2.raw.createServer(options, function(request, response) {
console.log("Receiving HTTP2 request!");
// response.writeHead(200);
response.end('Hello world from HTTP2!');
});
server.listen(8000);
However, it does not work. When connecting to this server from chrome, it shows downloading something. When I closed the server, the downloading is finished with blank file (26 bytes).
Does anyone know what is wrong here? Do I need to configure the browser? Thanks in advance!
Chrome and all other browsers only support HTTP/2 over TLS (h2) and not plain HTTP/2 (h2c). So your browser does not understand what is returned from the server and apparently node-http2 does not send a proper error response when it receives a non-http2 request.
The problem seems not just from the browser. Using [curl] curllink that supports http2 over an http:// URL does not working either. Following is the output from the curl:
$ curl -I --http2 http://54.208.83.136:8000/ -v -k
* Trying 54.208.83.136...
* Connected to 54.208.83.136 (54.208.83.136) port 8000 (#0)
> HEAD / HTTP/1.1
> Host: 54.208.83.136:8000
> User-Agent: curl/7.47.1
> Accept: */*
> Connection: Upgrade, HTTP2-Settings
> Upgrade: h2c
> HTTP2-Settings: AAMAAABkAAQAAP__
>
As we see from the curl output. It sends http/1.1 Upgrade request with proper headers set as it supposed to do according to the [http2 rfc] rfclink.
On the server side, the logs were very long, so I present here only the content of msg in the relevant three logs.
New incoming HTTP/2 connection
Client connection header prelude does not match
PROTOCOL ERROR, Fatal error, closing connection
So basically the server closed the connection because the client connection header prelude does not match. By checking the code, I figured out the error was originated from the readPrelude function of [endpoint.js] endpointlink. It is a function to read the client header, but I don't know what is wrong in the client header :(.
Thus maybe I can say the node-http2 module does not support http2 over plaintext.
Update: it turns out that I was wrong. The node-http2 module do support http2 over plaintext with direct connecting, it does not support HTTP/2 server with Upgrade from HTTP/1.1. The problem resulted from the client side using Upgrade mechanism to connect to the server not supporting Upgrade. Using nghttp client to connect sever with prior knowledge works as follows.
$ nghttp http://127.0.0.1:8000/
Hello world from HTTP2!
nghttpd server also supports HTTP2 without TLS, even though it does not support HTTP Upgrade.
$ nghttpd -d /Documents/Proxy 8080 --no-tls -v
So I highly suggest to use nghttp when you want to test HTTP2 without TLS.

Resources