libetl/curl

java.lang.IndexOutOfBoundsException: Index: 1, Size: 1

OneXeor opened this issue ยท 31 comments

Hi, I always receive
Unexpected exception org.toilelibre.libe.curl.Curl$CurlException: java.util.concurrent.ExecutionException: java.lang.IndexOutOfBoundsException: Index: 1, Size: 1 at org.toilelibre.libe.curl.Curl.curl(Curl.java:37) at org.toilelibre.libe.curl.Curl$CurlArgumentsBuilder.run(Curl.java:74) at safeApi.services.key.KeyDataService.checkKey(KeyDataService.java:140) at safeApi.services.key.KeyDataService.updatePhone(KeyDataService.java:96) at safeApi.services.key.KeyDataController.lambda$changePhone$0(KeyDataController.java:72) at spark.ResponseTransformerRouteImpl$1.handle(ResponseTransformerRouteImpl.java:47) at spark.http.matching.Routes.execute(Routes.java:61) at spark.http.matching.MatcherFilter.doFilter(MatcherFilter.java:130) at spark.embeddedserver.jetty.JettyHandler.doHandle(JettyHandler.java:50) at org.eclipse.jetty.server.session.SessionHandler.doScope(SessionHandler.java:1568) at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:141) at org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:132) at org.eclipse.jetty.server.Server.handle(Server.java:564) at org.eclipse.jetty.server.HttpChannel.handle(HttpChannel.java:317) at org.eclipse.jetty.server.HttpConnection.onFillable(HttpConnection.java:251) at org.eclipse.jetty.io.AbstractConnection$ReadCallback.succeeded(AbstractConnection.java:279) at org.eclipse.jetty.io.FillInterest.fillable(FillInterest.java:110) at org.eclipse.jetty.io.ChannelEndPoint$2.run(ChannelEndPoint.java:124) at org.eclipse.jetty.util.thread.Invocable.invokePreferred(Invocable.java:128) at org.eclipse.jetty.util.thread.Invocable$InvocableExecutor.invoke(Invocable.java:222) at org.eclipse.jetty.util.thread.strategy.EatWhatYouKill.doProduce(EatWhatYouKill.java:294) at org.eclipse.jetty.util.thread.strategy.EatWhatYouKill.produce(EatWhatYouKill.java:126) at org.eclipse.jetty.util.thread.QueuedThreadPool.runJob(QueuedThreadPool.java:673) at org.eclipse.jetty.util.thread.QueuedThreadPool$2.run(QueuedThreadPool.java:591) at java.lang.Thread.run(Thread.java:748) Caused by: java.util.concurrent.ExecutionException: java.lang.IndexOutOfBoundsException: Index: 1, Size: 1 at java.util.concurrent.CompletableFuture.reportGet(CompletableFuture.java:357) at java.util.concurrent.CompletableFuture.get(CompletableFuture.java:1895) at org.toilelibre.libe.curl.Curl.curl(Curl.java:35) ... 24 more Caused by: java.lang.IndexOutOfBoundsException: Index: 1, Size: 1 at java.util.ArrayList.rangeCheck(ArrayList.java:657) at java.util.ArrayList.get(ArrayList.java:433) at org.toilelibre.libe.curl.HttpClientProvider.setCaCertificateEntry(HttpClientProvider.java:178) at org.toilelibre.libe.curl.HttpClientProvider.lambda$generateKeyStore$2(HttpClientProvider.java:89) at java.util.stream.Streams$RangeIntSpliterator.forEachRemaining(Streams.java:110) at java.util.stream.IntPipeline$Head.forEach(IntPipeline.java:557) at org.toilelibre.libe.curl.HttpClientProvider.generateKeyStore(HttpClientProvider.java:89) at org.toilelibre.libe.curl.HttpClientProvider.addClientCredentials(HttpClientProvider.java:71) at org.toilelibre.libe.curl.HttpClientProvider.handleSSLParams(HttpClientProvider.java:134) at org.toilelibre.libe.curl.HttpClientProvider.prepareHttpClient(HttpClientProvider.java:62) at org.toilelibre.libe.curl.Curl.lambda$curlAsync$1(Curl.java:46) at java.util.concurrent.CompletableFuture$AsyncSupply.run(CompletableFuture.java:1590) at java.util.concurrent.CompletableFuture$AsyncSupply.exec(CompletableFuture.java:1582) at java.util.concurrent.ForkJoinTask.doExec(ForkJoinTask.java:289) at java.util.concurrent.ForkJoinPool$WorkQueue.runTask(ForkJoinPool.java:1056) at java.util.concurrent.ForkJoinPool.runWorker(ForkJoinPool.java:1692) at java.util.concurrent.ForkJoinWorkerThread.run(ForkJoinWorkerThread.java:157)

My request look like:
HttpResponse response = curl()
.key("./my.key")
.cert("./mycert.pem")
.cacert("./ca-chain.crt")
.xUpperCase("POST")
.hUpperCase("accept: application/xml")
.hUpperCase("Content-Type: application/xml")
.databinary("@- <<EOFSOMEDATAEOF")
.run("https://url:port/");

Hi.
Ok, looks like your ca cert was filtered.
You should make sure that the certificate chain is fully given in pem format, or der, or p12 or jks.
I am not sure if .crt format is supported by curl java.
Give me some time to understand the trouble.

I lost 2 days and I can't find solution make request with provide the rsa key to a server.
I'm ashamed, but it's true.
Usual curl or "Postman" works fine with this request.
And I decided to use your library for that.
Sorry for my bad English)

.pem is just a key pair (crt + key)

If you lost your key, maybe curl java will not be able to work on your request

No, I have the key. And how I said above, curl from terminal or through postman works well.

What about converting your ca-chain certificate from crt format to pem format ?

https://stackoverflow.com/questions/991758/how-to-get-pem-file-from-key-and-crt-files

then

HttpResponse response = curl()
.key("./my.key")
.cert("./mycert.pem")
.cacert("./ca-chain.pem")
.xUpperCase("POST")
.hUpperCase("accept: application/xml")
.hUpperCase("Content-Type: application/xml")
.databinary("@- <<EOFSOMEDATAEOF")
.run("https://url:port/");

The ca cert will not be filtered and you will be able to move forward

Ok I will try. But im not sure that will help, because in postman I set only "mycert.pem", "my.key" and password for key, that is working without ca-cert.pem.

hmm... "password for key" that is disturbing,

you should stip off the password from the key before using curl for java.

And Im just tried curl from terminal without ca-chain and that also work
look like:
curl -v \ --key ./my.key \ --cert ./mycert.pem \ -X POST \ -H "accept: application/xml" \ -H "Content-Type: application/xml" \ "https://....:..../" \ --data-binary @- <<EOF ........ EOF

do you think remove password from the key may will help?

true.

And once done, just remove the ca chain certificate, because I think that the mycert.pem already contains the CA cert.

HttpResponse response = curl()
.key("./my.unprotected.key")
.cert("./mycert.pem")
.xUpperCase("POST")
.hUpperCase("accept: application/xml")
.hUpperCase("Content-Type: application/xml")
.databinary("@- <<EOFSOMEDATAEOF")
.run("https://url:port/");

hmm
now I received:
Exception in thread "main" org.toilelibre.libe.curl.Curl$CurlException: java.util.concurrent.ExecutionException: java.lang.NoSuchMethodError: org.apache.http.conn.ssl.SSLConnectionSocketFactory.getDefaultHostnameVerifier()Ljavax/net/ssl/HostnameVerifier; at org.toilelibre.libe.curl.Curl.$(Curl.java:21) at safeApi.utils.Pinning.main(Pinning.java:53) Caused by: java.util.concurrent.ExecutionException: java.lang.NoSuchMethodError: org.apache.http.conn.ssl.SSLConnectionSocketFactory.getDefaultHostnameVerifier()Ljavax/net/ssl/HostnameVerifier; at java.util.concurrent.CompletableFuture.reportGet(CompletableFuture.java:357) at java.util.concurrent.CompletableFuture.get(CompletableFuture.java:1895) at org.toilelibre.libe.curl.Curl.$(Curl.java:19) ... 1 more Caused by: java.lang.NoSuchMethodError: org.apache.http.conn.ssl.SSLConnectionSocketFactory.getDefaultHostnameVerifier()Ljavax/net/ssl/HostnameVerifier; at org.toilelibre.libe.curl.HttpClientProvider.handleSSLParams(HttpClientProvider.java:139) at org.toilelibre.libe.curl.HttpClientProvider.prepareHttpClient(HttpClientProvider.java:62) at org.toilelibre.libe.curl.Curl.lambda$curlAsync$1(Curl.java:46) at java.util.concurrent.CompletableFuture$AsyncSupply.run(CompletableFuture.java:1590) at java.util.concurrent.CompletableFuture$AsyncSupply.exec(CompletableFuture.java:1582) at java.util.concurrent.ForkJoinTask.doExec(ForkJoinTask.java:289) at java.util.concurrent.ForkJoinPool$WorkQueue.runTask(ForkJoinPool.java:1056) at java.util.concurrent.ForkJoinPool.runWorker(ForkJoinPool.java:1692) at java.util.concurrent.ForkJoinWorkerThread.run(ForkJoinWorkerThread.java:157)

But im use so request:
String response = $("curl " +
"--key ./new.key \\n" +
"--cert ./mycert.pem \\n" +
"-X POST \\n" +
"-H "accept: application/xml" \\n" +
"-H "Content-Type: application/xml" \\n" +
"https://....:..../" +
"--data-binary @- <<EOFsomedataEOF");

Because builder throw exception. Sorry I forgot tell about:
" Unrecognized option: --databinary"

Apache HttpComponents from the curl lib is offending provided Apache HttpComponents from your server.

Can you try in an unit test ?

data binary is quite new in 0.0.14, may not be working as expected in full text command mode.

curl lib uses apache httpcomponents 4.5.2

What test can I do? :)

you can create a standalone project or test that uses curl lib, so you don't have to cope with offending classes (yet)

because your jetty seems to be conflicting with curl (I don't know which version of apache hc your server relies on, but it seems to be incompatible : java.lang.NoSuchMethodError)

Hmm..
In clean project I also received
java.util.concurrent.ExecutionException: java.lang.ArrayIndexOutOfBoundsException: 1 at org.toilelibre.libe.curl.Curl.$(Curl.java:21) at Main.main(Main.java:19)

I mean, even after omitting the cacert ?

HttpResponse response = curl()
.key("./my.unprotected.key")
.cert("./mycert.pem")
.xUpperCase("POST")
.hUpperCase("accept: application/xml")
.hUpperCase("Content-Type: application/xml")
.databinary("@- <<EOFSOMEDATAEOF")
.run("https://url:port/");

Can you give me the full stacktrace ?

Yes, even so. :(
Stacktrace from raw curl:
Exception in thread "main" org.toilelibre.libe.curl.Curl$CurlException: java.util.concurrent.ExecutionException: java.lang.ArrayIndexOutOfBoundsException: 1 at org.toilelibre.libe.curl.Curl.$(Curl.java:21) at Main.main(Main.java:22) Caused by: java.util.concurrent.ExecutionException: java.lang.ArrayIndexOutOfBoundsException: 1 at java.util.concurrent.CompletableFuture.reportGet(CompletableFuture.java:357) at java.util.concurrent.CompletableFuture.get(CompletableFuture.java:1895) at org.toilelibre.libe.curl.Curl.$(Curl.java:19) ... 1 more Caused by: java.lang.ArrayIndexOutOfBoundsException: 1 at org.toilelibre.libe.curl.HttpRequestProvider.lambda$setHeaders$7(HttpRequestProvider.java:180) at java.util.stream.ReferencePipeline$3$1.accept(ReferencePipeline.java:193) at java.util.stream.ReferencePipeline$3$1.accept(ReferencePipeline.java:193) at java.util.stream.ReferencePipeline$2$1.accept(ReferencePipeline.java:175) at java.util.Spliterators$ArraySpliterator.forEachRemaining(Spliterators.java:948) at java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:481) at java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:471) at java.util.stream.ForEachOps$ForEachOp.evaluateSequential(ForEachOps.java:151) at java.util.stream.ForEachOps$ForEachOp$OfRef.evaluateSequential(ForEachOps.java:174) at java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234) at java.util.stream.ReferencePipeline.forEach(ReferencePipeline.java:418) at org.toilelibre.libe.curl.HttpRequestProvider.setHeaders(HttpRequestProvider.java:180) at org.toilelibre.libe.curl.HttpRequestProvider.prepareRequest(HttpRequestProvider.java:48) at org.toilelibre.libe.curl.Curl.lambda$curlAsync$1(Curl.java:46) at java.util.concurrent.CompletableFuture$AsyncSupply.run(CompletableFuture.java:1590) at java.util.concurrent.CompletableFuture$AsyncSupply.exec(CompletableFuture.java:1582) at java.util.concurrent.ForkJoinTask.doExec(ForkJoinTask.java:289) at java.util.concurrent.ForkJoinPool$WorkQueue.runTask(ForkJoinPool.java:1056) at java.util.concurrent.ForkJoinPool.runWorker(ForkJoinPool.java:1692) at java.util.concurrent.ForkJoinWorkerThread.run(ForkJoinWorkerThread.java:157)

And from builder
Exception in thread "main" org.toilelibre.libe.curl.Curl$CurlException: java.util.concurrent.ExecutionException: java.lang.ArrayIndexOutOfBoundsException: 1 at org.toilelibre.libe.curl.Curl.curl(Curl.java:37) at org.toilelibre.libe.curl.Curl$CurlArgumentsBuilder.run(Curl.java:74) at Main.main(Main.java:20) Caused by: java.util.concurrent.ExecutionException: java.lang.ArrayIndexOutOfBoundsException: 1 at java.util.concurrent.CompletableFuture.reportGet(CompletableFuture.java:357) at java.util.concurrent.CompletableFuture.get(CompletableFuture.java:1895) at org.toilelibre.libe.curl.Curl.curl(Curl.java:35) ... 2 more Caused by: java.lang.ArrayIndexOutOfBoundsException: 1 at org.toilelibre.libe.curl.HttpRequestProvider.lambda$setHeaders$7(HttpRequestProvider.java:180) at java.util.stream.ReferencePipeline$3$1.accept(ReferencePipeline.java:193) at java.util.stream.ReferencePipeline$3$1.accept(ReferencePipeline.java:193) at java.util.stream.ReferencePipeline$2$1.accept(ReferencePipeline.java:175) at java.util.Spliterators$ArraySpliterator.forEachRemaining(Spliterators.java:948) at java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:481) at java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:471) at java.util.stream.ForEachOps$ForEachOp.evaluateSequential(ForEachOps.java:151) at java.util.stream.ForEachOps$ForEachOp$OfRef.evaluateSequential(ForEachOps.java:174) at java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234) at java.util.stream.ReferencePipeline.forEach(ReferencePipeline.java:418) at org.toilelibre.libe.curl.HttpRequestProvider.setHeaders(HttpRequestProvider.java:180) at org.toilelibre.libe.curl.HttpRequestProvider.prepareRequest(HttpRequestProvider.java:48) at org.toilelibre.libe.curl.Curl.lambda$curlAsync$1(Curl.java:46) at java.util.concurrent.CompletableFuture$AsyncSupply.run(CompletableFuture.java:1590) at java.util.concurrent.CompletableFuture$AsyncSupply.exec(CompletableFuture.java:1582) at java.util.concurrent.ForkJoinTask.doExec(ForkJoinTask.java:289) at java.util.concurrent.ForkJoinPool$WorkQueue.runTask(ForkJoinPool.java:1056) at java.util.concurrent.ForkJoinPool.runWorker(ForkJoinPool.java:1692) at java.util.concurrent.ForkJoinWorkerThread.run(ForkJoinWorkerThread.java:157)

It does not fail at the same place.
Give me some time.

I have written an unit test in my project, and it works fine :

    @Test
    public void complexOne() {
         $("curl -k " +
                "--cert src/test/resources/clients/libe/libe.pem \n" +
                "--key src/test/resources/clients/libe/libe.key \n" +
                "-X POST \n" +
                "-H \"accept: application/xml\" \n" +
                "-H \"Content-Type: application/xml\" \n" +
                "https://localhost:%d/ " +
                "--data-binary @src/test/resources/form.sh");
         }

databinary does not support <<<EOF bash notation

leave a white space between the url and --data-binary

it's really funny, I did it!!! I rewrote ssl socket factory for working with my jks and it works fine. :)
But I could not understand why curl lib is not working with my key. Also now I receive the same I received while using sslSocketFactory before...

Exception in thread "main" org.toilelibre.libe.curl.Curl$CurlException: java.util.concurrent.ExecutionException: org.toilelibre.libe.curl.Curl$CurlException: javax.net.ssl.SSLHandshakeException: Received fatal alert: handshake_failure at org.toilelibre.libe.curl.Curl.$(Curl.java:21) at Main.main(Main.java:19) Caused by: java.util.concurrent.ExecutionException: org.toilelibre.libe.curl.Curl$CurlException: javax.net.ssl.SSLHandshakeException: Received fatal alert: handshake_failure at java.util.concurrent.CompletableFuture.reportGet(CompletableFuture.java:357) at java.util.concurrent.CompletableFuture.get(CompletableFuture.java:1895) at org.toilelibre.libe.curl.Curl.$(Curl.java:19) ... 1 more Caused by: org.toilelibre.libe.curl.Curl$CurlException: javax.net.ssl.SSLHandshakeException: Received fatal alert: handshake_failure at org.toilelibre.libe.curl.Curl.lambda$curlAsync$1(Curl.java:50) at java.util.concurrent.CompletableFuture$AsyncSupply.run(CompletableFuture.java:1590) at java.util.concurrent.CompletableFuture$AsyncSupply.exec(CompletableFuture.java:1582) at java.util.concurrent.ForkJoinTask.doExec(ForkJoinTask.java:289) at java.util.concurrent.ForkJoinPool$WorkQueue.runTask(ForkJoinPool.java:1056) at java.util.concurrent.ForkJoinPool.runWorker(ForkJoinPool.java:1692) at java.util.concurrent.ForkJoinWorkerThread.run(ForkJoinWorkerThread.java:157) Caused by: javax.net.ssl.SSLHandshakeException: Received fatal alert: handshake_failure at sun.security.ssl.Alerts.getSSLException(Alerts.java:192) at sun.security.ssl.Alerts.getSSLException(Alerts.java:154) at sun.security.ssl.SSLSocketImpl.recvAlert(SSLSocketImpl.java:2033) at sun.security.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:1135) at sun.security.ssl.SSLSocketImpl.performInitialHandshake(SSLSocketImpl.java:1385) at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1413) at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1397) at org.apache.http.conn.ssl.SSLConnectionSocketFactory.createLayeredSocket(SSLConnectionSocketFactory.java:394) at org.apache.http.conn.ssl.SSLConnectionSocketFactory.connectSocket(SSLConnectionSocketFactory.java:353) at org.apache.http.impl.conn.DefaultHttpClientConnectionOperator.connect(DefaultHttpClientConnectionOperator.java:141) at org.apache.http.impl.conn.PoolingHttpClientConnectionManager.connect(PoolingHttpClientConnectionManager.java:353) at org.apache.http.impl.execchain.MainClientExec.establishRoute(MainClientExec.java:380) at org.apache.http.impl.execchain.MainClientExec.execute(MainClientExec.java:236) at org.apache.http.impl.execchain.ProtocolExec.execute(ProtocolExec.java:184) at org.apache.http.impl.execchain.RetryExec.execute(RetryExec.java:88) at org.apache.http.impl.client.InternalHttpClient.doExecute(InternalHttpClient.java:184) at org.apache.http.impl.client.CloseableHttpClient.execute(CloseableHttpClient.java:82) at org.apache.http.impl.client.CloseableHttpClient.execute(CloseableHttpClient.java:107) at org.apache.http.impl.client.CloseableHttpClient.execute(CloseableHttpClient.java:55) at org.toilelibre.libe.curl.Curl.lambda$curlAsync$1(Curl.java:46)

Sorry for the time spent and thank you very much.

handshake failure : https over http ?

Good luck, sorry for the loss of time.