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.
Related
I need to upgrade my request from being served by HTTP1.1 to HTTP/2.
This is so far what I have tried.
public class H2cUpgradeRequestInterceptor implements Interceptor {
private static final Log logger = LogFactory.getLog(H2cUpgradeRequestInterceptor.class);
#Override
public Response intercept(Chain chain) throws IOException {
Request request = chain.request();
Request upgradeRequest = request.newBuilder().addHeader("Connection", "Upgrade, HTTP2-Settings")
.addHeader("Upgrade", "h2c").addHeader("HTTP2-Settings", "AAMAAABkAARAAAAAAAIAAAAA").build();
Response upgradeResponse = chain.proceed(upgradeRequest);
if (upgradeResponse != null && upgradeResponse.code() == HttpStatus.SC_SWITCHING_PROTOCOLS) {
logger.debug("Switching Protocols success"); // Success. Got 101 in reply.
}
Response response = chain.proceed(request);
if (response.protocol() == Protocol.HTTP_2) { // This is returning HTTP1.1 as protocol
logger.debug("Used upgraded h2c protocol");
}
return response;
}
}
My server has h2c enabled. I am also receiving 101 Switching Protocols in my first chain.proceed() call. But the next proceed() always gives me HTTP1.1 as protocol even if switching protocols is successful. Is it right right way of achieving protocol upgrade? And, if yes, how can I make sure it uses HTTP2 after switching protocol is successful?
Closing this since, as per the docs
I need not send the request again.
If the Upgrade header field is received in a GET request and the
server decides to switch protocols, it first responds with a 101
(Switching Protocols) message in HTTP/1.1 and then immediately follows
that with the new protocol's equivalent of a response to a GET on the
target resource. This allows a connection to be upgraded to protocols
with the same semantics as HTTP without the latency cost of an
additional round trip.
Following back here
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.
I am using a HttpURLConnection instance in order to connect to a URL.
I am then calling the getResponseCode method in order to determine the connection state.
I am polling the connection with this method, until the returned response-code is NOT 1xx:
HttpURLConnection con = (HttpURLConnection)new URL(ref).openConnection();
int responseType = con.getResponseCode()/100;
while (responseType == 1)
{
Thread.sleep(10);
responseType = con.getResponseCode()/100;
}
switch (responseType)
{
...
}
What is the recommended time to sleep inside the loop? (here set to 10ms).
Is there any time period (min, max, average) defined in the HTTP standard?
The status code "100 continue" is usually sent by the server after it got the request header of the POST request, to signal the client that it can follow up with the POST body. This way the server can reject requests early based on the request header (e.g. authorization required) without wasting resources on the client. The final response will then be sent after the server received the request body from the client, which might be immediately or hours later, depending on how fast the clients sends the request body.
I am trying to develop a class that allows me to run a socket on a thread, and that at any time allows me to send through it data, as well as receive a notifications when data arrives. It should assume no things such as only receiving a message after it has sent a message first, etc.
By some reason, the following code is printing the response for only the first request:
public static void main(String[] args) throws IOException {
TCPClient client = new TCPClient(new TCPClientObserver());
client.connect("www.microsoft.com", 80);
sleep(1000);
client.send("HTTP GET");
sleep(5000);
client.send("XYZ");
}
printing
echo: <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN""http://www.w3.org/TR/html4/strict.dtd">
echo: <HTML><HEAD><TITLE>Bad Request</TITLE>
echo: <META HTTP-EQUIV="Content-Type" Content="text/html; charset=us-ascii"></HEAD>
echo: <BODY><h2>Bad Request - Invalid URL</h2>
echo: <hr><p>HTTP Error 400. The request URL is invalid.</p>
echo: </BODY></HTML>
Here is the core logic of the socket:
echoSocket = new Socket("www.microsoft.com", 80);
out = new PrintWriter(echoSocket.getOutputStream(), true);
in = new BufferedReader(new InputStreamReader(
echoSocket.getInputStream()));
while (true) {
String response = in.readLine();
if (response != null)
System.out.println("echo: " + response);
}
I guess the problem lies in my loop?
The full test code of my app can be seen here:
http://codepad.org/bmHwct35
Thanks
The problem is not the loop, but rather the first request you send. "HTTP GET" is invalid request and the server should respond with "400 Bad request", then close the connection. That's why you don't get response for your second message. Try a valid HTTP request e.g. "GET / HTTP/1.1\r\nHost: www.microsoft.com\r\n\r\n" instead. HTTP 1.1 connections are keep-alive by default, so you'll be able to send several of them and receive subsequent responses.
Assuming the HTTP 400 is what you expected, you need to break out of your loop if readLine() returns null. This is usually written like this:
while ((line = in.readLine()) != null)
{
// ...
}
The first you send is an invalid request and after replying the server will close the connection. In your code you are then stuck in the while (true) loop as you will keep getting null back from readLine as the connection/stream is closed (end of stream reached).
while (true) { // <-- never terminates
String response = in.readLine();
if (response != null) // <- now null all the time
System.out.println("echo: " + response);
}
The problem is that HTTP servers talk the HTTP protocol, and your client code is not talking the protocol properly. Instead it is opening a plain socket and writing random stuff that seems to be based on guesswork.
The HTTP protocol is specified in this document. If you read it, you will see that what you are doing is nothing like what a client is supposed to do.
I recommend that you don't attempt to implement your client this way. Implementing the client side of the HTTP protocol from scratch is too much work ... and the world does not need yet another flakey HTTP client. Either use the standard URL / HttpURLConnection APIs, or use a 3rd-party HTTP client library.
In your case, the 400 response is most likely a consequence of sending a malformed request. An HTTP GET request (indeed any HTTP request) is supposed to include the target URL in the first line. Read the spec.
I have a situation as below:
I have 2 web applications running on Tomcat. Initially User gets logged in to the Application 1 and then. There is a link to the Application 2. On Clicking the link User should be redirected to second application.
Both applications using LDAP authentication.
Now, the problem here is second application has its own Authentication system.
So, We are planning to implicitly authenticate the user which is logged in the first system.
I have written a servlet, which gets executed when I click on link for App2 in the App1.
I am trying to use below code which should call Servlet "ldap-login" on app2 with given parameters.Parameter names are correct.
String targetURL = "http://localhost:8080/app2/ldap-login";
HttpClient client = new HttpClient();
PostMethod doPost = new PostMethod(targetURL);
//doPost.getParams().setBooleanParameter(HttpMethodParams.USE_EXPECT_CONTINUE, true);
doPost.addParameter("login_netid", "alice");
doPost.addParameter("login_password", "alice");
try {
int status = client.executeMethod(doPost);
if (status == HttpStatus.SC_OK) {
// redirect
response.sendRedirect("http://localhost:8080/app2/myPage");
} else {
System.out.println("Service failed, Response Code= " +
HttpStatus.getStatusText(status));
System.out.println("Response Body --> " + doPost.getResponseBodyAsString());
}
} catch (Exception ex) {
System.out.println("ERROR: " +
ex.getClass().getName() + " "+ ex.getMessage());
ex.printStackTrace();
} finally {
doPost.releaseConnection();
}
But I am getting Response "Moved temporarily".
Can anyone suggest me any alternate ?
A 302 Moved Temporarily response is just a redirect. It's exactly the kind of response which you would get when you do response.sendRedirect(). You can also very good get a redirect as a response to a successful login. I suggest to verify on the second application if it isn't indeed redirecting when the login is successful. You should then check if the response code is 302 instead of 200. Or, alternatively, you need to tell HttpClient to follow any redirects automatically.
Even more, if the login actually failed, what kind of response would you get from the second application? Would it throw an exception and thus return a response code of 500? Or would it just conditionally set some error message in the request scope and redisplay the JSP by a forward and thus keep a response code of 200? How would you then distinguish a 200 on a failed login from a 200 on a successful login?
Unrelated to the concrete problem, your approach will likely not work if the second application does not share the same session as the first application. A login is usually stored in the session, but you're not maintaining the session anywhere. Anyway, that's subject for a new question :)
As per the API doc, the sendRedirect call does a temporary redirect. As #BalusC mentioned, you need to handle response code SC_MOVED_TEMPORARILY or SC_FOUND.
The reason it's doing a redirect after login (or might be after any POST request) could be to avoid the Double Submit Problem. Here is another article on that one.