How one is supposed to tell OkHttp that a connection to an HTTP server should be closed after a request has finished?
Suppose I use the following code to make a request to google.com
OkHttpClient cl = new OkHttpClient();
Request req = new Request.Builder()
.url("http://www.google.com")
.header("Connection", "close")
.get()
.build();
Response res = cl.newCall(req).execute();
System.out.println("Response message: " + res.message());
System.out.println("Reponse body: " + res.body().string());
by using "Connection: close" I'm able to get the remote server to send a FIN (if I don't, the remote server just hangs awaiting for new requests). Still, on the client side no FIN is produced, and the connection stays half opened apparently for an indefinitive amount of time.
Ugh, it's a regression in OkHttp 2.0.0-RC1. Fix is out for review.
Related
I have Java 11.0.1 installed in MacOs Mojave and I started a local
Vertx http server which listens on http://0.0.0.0:8085/home (Just
return "hello world").
However, if I send request to 0.0.0.0:8085/home programmatically by
using java, it takes 5 seconds to reach local server. But if I
send to localhost:8085/home, it will immediately reach server and
receive response.
Besides, I tried Chrome, cURL and Python to send http request to both
0.0.0.0:8085/home and localhost:8085/home, both of them will immediately receive response. So is this a Java 11 bug or not?
String url = "http://0.0.0.0:8085/home" // Or http://localhost:8085/home;
URL obj = new URL(url);
HttpURLConnection con = (HttpURLConnection) obj.openConnection();
System.out.println(con.getResponseCode()); // 5 seconds to receive
If I use Java 11 Http Client new feature, it will hang forever.
HttpClient client = HttpClient.newHttpClient();
HttpRequest request = HttpRequest.newBuilder().uri(URI.create("http://localhost:8085/home")).build();
HttpResponse response = client.send(request, HttpResponse.BodyHandlers.ofString());
System.out.println(response.statusCode());
This question already has answers here:
java.io.IOException: unexpected end of stream on Connection in android
(12 answers)
Closed 3 years ago.
Calling one of our in-house web services seems to be giving the following error:
java.io.IOException: unexpected end of stream on Connection{webservicessandbox.xxx.com:443, proxy=DIRECT# hostAddress=174.143.185.13 cipherSuite=TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA protocol=http/1.1} (recycle count=0)
From what I've seen elsewhere, this is being pointed to as a server issue, but we're not seeing this problem when the WS is being called in browser or in IOS. I've used both OkHTTP and a manual HTTPUrlConnection implementation and it hasn't seemed to make any difference. Does anyone have any ideas?
OKHttp:
OkHttpClient client = new OkHttpClient();
Request request = new Request.Builder()
.addHeader("Authorization", "Bearer " + apiToken)
.addHeader("content-type", "application/json")
.url(uri)
.build();
HTTPURLConnection:
URL myURL = new URL(uri);
HttpsURLConnection myConnection = (HttpsURLConnection) myURL.openConnection();
myConnection.setConnectTimeout(TIMEOUT_MILLISEC);
myConnection.setDoOutput(false);
myConnection.setRequestMethod("GET");
myConnection.setRequestProperty("Authorization", "Bearer " + apiToken);
myConnection.setRequestProperty("content-type", "application/json");
int respCode = myConnection.getResponseCode();
Please try the potential solutions (in my opinion) below:
1- Try to use retryOnConnectionFailure(true) as below:
OkHttpClient client = new OkHttpClient.Builder()
.retryOnConnectionFailure(true)
.build();
2- Try to add: request.addHeader("Connection","close") (most cases this is the solution, respecting to Kartik's answer.)
Request request = new Request.Builder()
.addHeader("Authorization", "Bearer " + apiToken)
.addHeader("content-type", "application/json")
.addHeader("Connection","close")
.url(uri)
.build();
3- Please increase the response time of the server (set it as high as possible) and try again.
Also see: OkHTTP Websocket: Unexpected end of steam on Connection
Both the client and server needs to close the connection once they are finished.
In your OkHttp request builder, add this line: .header("Connection", "close").
Also check the network tab of your browser inspector to see which headers the browser is sending. Match those headers in your code and it should work.
This error TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 is related to server. A possible reason could be, the server is shut down.
I'm trying to integrate a payment service 'Mollie' (http://www.mollie.nl) which works over HTTPS requests into a Java environment.
As for this posts i'll be using following request to explain:
Within PHP (since I have a PHP background) I can work with cURL:
$ curl -X GET https://api.mollie.nl/v1/methods \
-H "Authorization: Bearer API-KEY"
Which has a response:
Testing the REQUEST from DHC (or Postman) return correct response.
So within Java i'm using the Jersey library to try to access the Request:
Client client = Client.create();
WebResource webResource = client.resource("https://api.mollie.nl/v1/methods");
webResource.header("Authorization", "Bearer API-KEY");
ClientResponse response = webResource
.header("Content-Type", "application/json;charset=UTF-8")
.type("application/json")
.accept("application/json")
.get(ClientResponse.class);
int statusCode = response.getStatus();
if (statusCode == 401) {
throw new AuthenticationException("Invalid Username or Password");
}
String responseCall = response.getEntity(String.class);
When executing the Java code the request throws a ClientHandlerException:
HTTP Status 500 - com.sun.jersey.api.client.ClientHandlerException: java.net.ConnectException: Connection timed out: connect
I'm running the Java test from a Apache localhost server.
But I can't figure out why the Java request gives a timeout since the authentication header seems to be set correct (at least to me).
What I did notice is when visiting the path of the request https://api.mollie.nl/v1/methods it shows a pop-up for authentication.
It would be nice to get some usefull tips or information about this issue.
Am I missing something?
Thanks!
Given all is is working correctly (I'm not sure why it would cause a timeout), one thing I see wrong is your usage of
webResource.header("Authorization", "Bearer API-KEY");
header returns an WebResource.Builder, and does not add the header to the current WebResource. So the request you are sending doesn't have the header. You can check it by adding a LoggingFilter
client.addFilter(new com.sun.jersey.api.client.filter.LoggingFilter(System.out));
You can fix this by doing
ClientResponse response = webResource
.header("Authorization", "Bearer API-KEY");
.header("Content-Type", "application/json;charset=UTF-8")
Just moving the header to the method chaining.
I have resolved above issue. Apparently the work PROXY server was blocking outgoing HTTPS requests. Testing from a non-proxy environment fixed the issue. Thanks for all advice!
Have a java application which makes a http call to a ruby application which execute certain sql queries and gives back an http response of 200 to the java appilcation if success, My problem is the ruby application takes more than 5min to complete the execution while checking the log of the java application after almost 3min it is given as gateway time out exception.How to solve this problem?
java http call to ruby application:
GetMethod get = new GetMethod(URL to ruby application);
Exception exception = null;
try {
// Get HTTP client
HttpClient httpclient = new HttpClient();
int resultCode = httpclient.executeMethod(get);
// Display status code
if (log.isInfoEnabled()) {
log.info("response status code: "
+ resultCode);
// Display response
log.info("Response body: " + get.getResponseBodyAsString());
}
if (resultCode != 200) {
log.error("Failed with status code: "
+ resultCode);
log.error("Response body: " + get.getResponseBodyAsString());
}
}
You can use this response to change the timeout...
Something is wrong with the architecture because nobody is sending requests and wait 5 minutes for an answer in an application.
Probably you should send the requests and return "200" (OK) if all the parameters of the request are ok (so the queries can be done) and when the results are ready (after 5 minutes) you can do few things:
a. to use a socket connection between the server and the client and send to the client the result.
b. much more useful : to send a push notification with the results (don't forget that today you can load 4 k of data on the push notification.
I am trying to send multiple HTTP POST over single socket connection , but EPIPE broken once I read inputstream.
mBufferedWriter.write("POST " + "/base/mypath" + " HTTP/1.1" + "\r\n");
mBufferedWriter.write("Host: " + mIp + "\r\n");
mBufferedWriter.write("Content-Length: " + json.toString().length()"\r\n");
mBufferedWriter.write("Content-Type: application/json\r\n");
mBufferedWriter.write("Connection: Keep-Alive\r\n\r\n");
mBufferedWriter.write(json.toString() + "\r\n");
mBufferedWriter.flush();
My first POST will reach server. Am trying to achieve pipelining. Set keep-alive for socket also
HTTP Pipelining involves more than just re-using an existing connection (HTTP Keep-Alive). Pipelining involves having multiple HTTP requests in flight over a single connection at the same time, where a client sends an HTTP request but does not wait for its response before sending the next HTTP request on the same connection. Both client and server have to implement support for pipelining in order to use it effectively. Even then, there are issues related to pipelining POST requests, so they should nver be pipelined. HTTP Pipelining is discussed in RFC 2616 Sections 8.1.1 and 8.1.2.2.
If you are not actually implementing Pipelining, only Keep-Alive, then you have to pay attention to the server's Connection response header, as it tells you whether you are allowed to send a new HTTP request over the same connection or not. For an HTTP 1.1 response, if the server sends a Connection: close header, then the socket is going to be closed by the server after it sends the response, so you will have to create a new connection before sending the next HTTP request.
You can use Apache HTTP client (http://hc.apache.org/httpcomponents-client-ga/) or http://developer.android.com/reference/org/apache/http/client/package-summary.html and set an Thread safe client connection manager.