managing keep-alive http connection inside servlet - java

Suppose a browser makes a request
asking for the server to keep the connection alive
(connection: keep-alive).
And this request requires the invocation of a servlet.
Inside my servlet should I care to choose the best
way to send data (chunked or indicating
the lenght of the body ) ??
if the server does that for me , why , inside my servlet ,
I'm able to modyfy headers like:
content-length
and transfer encoding ?
thanks

If you know the body length up front, you should set Content-Length header before writing body.
Otherwise do nothing; the servlet container should be able to automatically add Transfer-Encoding, and chunk-ify your body. That is subject to client/request version and Connection header.

Related

Java Server Side: send Http POST response - status only

Some third party is sending an Http Post request whenever something changes in their DB (e.g. when a contact has been updated, they send the contactID and 'contact_updated'). I have build a socket listener that catches those requests and is able to parse the information. However, I just can't get it to work to send back a response with the status '200 - OK'. Thus, the server on the client side keeps on trying (four times or so) to re-send the request.
Is there any, simple way to just send the response status without the need of adding external libs etc.?
It should be enough to send the string HTTP/1.1 200 OK back in your socket-listener.
If you have troubles, you can check out this answer, it shows how to use a HttpServer in Java just via plain JavaSE features.
Use
response.setStatus(HttpServletResponse.SC_OK);
to set the status code in your response header.
You may also set the content type.
response.setContentType("text/html;charset=UTF-8");

Get response header OkHttp

I need to check response header of HTTP request using OkHTTP library. before loading data I need to check it's last update time. The problem in that that the response body is about 2 MB so I need to get only Last-Modified header. Is it possible to load only response header without response body to increase the speed of the program`s RESTful actions?
You can send a HTTP HEAD request which only retrieves the headers. You only need to check if your server application supports HEAD requests.
The HEAD method is identical to GET except that the server MUST NOT
return a message-body in the response. The metainformation contained
in the HTTP headers in response to a HEAD request SHOULD be identical
to the information sent in response to a GET request. This method can
be used for obtaining metainformation about the entity implied by the
request without transferring the entity-body itself. This method is
often used for testing hypertext links for validity, accessibility,
and recent modification. (http://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html)
Example for OkHttp:
String url = ...
Request request = new Request.Builder().url(url).head().build();
The response body is streamed, so you can make the regular request, read the headers, and then decide whether or not to consume the body. If you don’t want the body, you can close() it without much waste.
There is a slight cost to the server to serve a response that might be abandoned. But the overall cost will be lower than making a HEAD and then a GET request unless you expect abandon a significant fraction (say > 90%) of requests.

An easy way to detect the end of http response (raw socket, java)?

I want to retrieve the server's response as is, with all headers. The first thing that comes to mind is to use raw sockets. As I have learned from the search, there are 3 ways to indicate the end of response:
(1) closing the connection;
(2) examining Content-Length;
(3) getting all chunks in the case of Transfer-Encoding: Chunked.
There is also
(4) the timeout method: assume that the timeout means end of data, but the latter is not really reliable.
I want a general-case solution and do not want to
add a Connection: close line to the request itself.
In addition, it is recommended to use an existing library rather than re-invent the wheel.
Question:
How do I use an existing package, preferably, something already present in Android, to detect the end of HTTP response while having access (without interference) to the raw data stream?
UPD: forgot to mention that the HTTP request is given to me as a sequence of bytes. Yes, it is for testing.
PS
relevant reading:
End of an HTTP Response
Detect the end of an HTTP Request in Java
Detect end of HTTP request body
How HTTP Server inform its clients that the response has ended
Proper handling of chuncked Http Response within Socket
Detect the end of a HTTP packet
Android socket & HTTP response headers
Java HTTP GET response waits until timeout
I suggest to use a the Apache HTTP client package (http://hc.apache.org/httpclient-3.x/ ) so you don't need to implement all the finicky details of the HTTP protocol.
The Apache Http Client will give you access to the headers and their content, which may be enough for you.
If you really need access to the actual character sequence sent by the server (e.g. for debugging purposes), you could then intercept the communication by replacing the connection socket factory with your own to create "intercepting" sockets which store all data transferred in a buffer where your code can access it later on. See http://hc.apache.org/httpcomponents-client-4.3.x/tutorial/html/connmgmt.html#d5e418

how to make http request same url with different ip's?

I would like to send an HTTP request and get the response body, but I have URL that is stored on multiple servers. Let's say I have this list:
www.mysite.com 192.168.1.31
www.mysite.com 192.168.1.32
and I want to make the request to all the the different servers (different IP's) but same URL
Is there any option to do that in Java?
Yes, you can do that. Define the URL as being what you want and using the IP address in place of a domain name. I.E. http://192.168.1.31/path/to/index.html Then add the "Host: www.mysite.com" header before issuing the request. Any HTTP/1.1 compliant server will use the value of that header as the domain with which it was accessed.
Exactly how you accomplish this depends on whatever library you're using to make the connection but they should all have the ability to set arbitrary headers -- just make sure it doesn't overwrite your custom "Host" header with one of its own from the URL. See this other StackOverflow question for examples of how to implement an HTTP request.
This works because on the wire it's all IP. You can try it yourself using nc, socket, or even telnet.
(open TCP connection to 192.168.1.31 port 80)
GET /path/to/index.html HTTP/1.1
Host: www.mysite.com
<--blank line signals end of headers

Java: Can I alter HTTP Headers And Read The Headers Server Side?

I have a legacy Java webapp that does MANY redirects and forwards. I'm trying to find a way in a ServletFilter to differentiate GET requests from those server side redirects and GET requests that come from the client side.
I was hoping to do that by adding an attribute as a flag, to the header before the redirect/forward is sent and then read it in the ServletFilter to route it accordingly.
I tried request.setAttribute("myflag", "yes") before the redirect and request.getAttribute("myflag") in the ServletFilter. All I got were null values.
Can I modify headers server side and read those modifications server side?
Thanks in advance for any tips.
You can use a HttpServletRequestWrapper, there is a comprehensive tutorial on how to do that here:
http://vangjee.wordpress.com/2009/02/25/how-to-modify-request-headers-in-a-j2ee-web-application/
don't use request.setAttribute()/request.getAttribute() , it's scopes on forwards.
you can use Cookies.
If your application sets a request attribute and then forwards the request, the filter (if executed) on the forwarded URI will see the request attribute values.
In contrast, if the application sets a request attribute and then issues a redirect on the response, the browser issues a new HTTP request to the next URI - so previous request object attributes are not persisted and you'll get null values.
You could use this technique to determine which requests were redirects vs forwards.
For example:
Servlet A executed at URI /webapp/a calls request.setAttribute("forward", Boolean.TRUE) and then response.sendRedirect("/webapp/b")
If you have a servlet filter mapped to /webapp/b, in the scenario above, request.getAttribute("forward") will be null.
If, however, /webapp/a asks RequestDispatcher to forward to /webapp/b, then the call to request.getAttribute("forward") within the servlet filter's doFilter() will yield Boolean.TRUE because the request object is the same. It can then deduce that the request was forwarded (or included) and not a redirect OR a direct GET request to /webapp/b.

Categories