Capturing Response Size - HttpServlet - java

I have an application where the users are accessing a servlet file which will read a .pdf file conditionally and send the .pdf file as response to the users request. The servlet code does not sets the content length on the response header.
In the above scenario I want to capture the Response Size of the each user request without making any changes in the servlet code.
At the same time I do not want to use the HttpServletResponseWrapper for some other reasons.
Please suggest me on the possible ways to achieve this.
Thanks in advance.

Every container supports Web Access Logging. Look for that and enable it. It will log the response content length along with other request and response parameters.

Related

java httpServer Post request work

I'm start learning java programming, and I want make a simple server application. I read about com.sun.net.httpserver.HttpServer and find a good example on this link: https://github.com/imetaxas/score-board-httpserver-corejava.
I understand how to do Get-request in url, but I don't know how POST works. I think it must be sent a form or data on the server.
I attach the link of project, which I'm learning, in readme the author wrote http://localhost:8081/2/score?sessionkey=UICSNDK - it's not working...
I wrote in url and get sessionkey: "localhost:8081/4711/login --> UICSNDK"
I wrote in url this for Post request: "localhost:8081/2/score?sessionkey=UICSNDK" - not working and in chrome return 404 bad request
3.wrote in url this:"localhost:8081/2/highscorelist"
Please help me, I am beginner.
The difference between GET and POST is that with a GET request the data you wish to pass to the endpoint is done by modifying the url itself by adding parameters to it.
With a POST any data you wish to send to the endpoint must be in the body of the request.
The body of a request is arbitrary data that comes after a blank line in the header The reqiest has the request line, following by any number of header attributes, then a blank line.
The server would need to know what the format of the body of the request was and parse it as appropriate.
Of course 'modern' frameworks like jax-rs allow you to automatically convert request data to objects, so that it is much simpler.

Redirect webpage after having sent some content

I am working with a web framework (uPortal) that is handling errors by just throwing an exception and then hanging. The framework works by rendering XML into HTML. When there is an exception, the browser recieves rendered content up to the XML template element that is failing, and then the browser just sits and waits for a timeout. Our team's theory is that the content is sent before the error occurs, which surprised me. Other frameworks I've worked with seem to finish rendering before sending content.
My question is, is there a way to redirect the browser after content has already been sent? In this case, we are in the middle of rendering the content of a <script> tag, but the error could occur potentially anywhere in the html.
My only current thought is to inject some javascript at the top of the page, and to try to change the framework's behavior to fail quickly and close the connection and add </body> and </html> tags when an error occurs. Then the above mentioned javascript would run on pageload and detect if the entire page's content was there and do a client-side redirect if not. Maybe it could look for a special hidden div at the bottom of the page.
Are there any examples of frameworks solving this problem differently or of people using similar framework working around this issue?
You must either capture the error, or capture the output in a buffer. If you can handle the exception, you can probably print a simple script tag like
<script> window.location.href = 'some_new_url';</script>
If the browser understands the doctype to be something related to HTML, it will execute that tag.
If you can capture the output in a buffer, when you handle the error you can decide to send an HTTP redirect to the browser and destroy the output buffer up to that point.
As for other frameowrks, in PHP, you can simply enable output buffering with ob_start(), which won't start sending content until the request is fully completed.
I don't know that framework, but
In http, every response has a response-code associated with it. Since the page is already half-way transferred / rendered that status code (usually "200") was sent (and received) already.
There's no way for the browser to accept another response code (like "301" for redirect) for the same response! Also the server is not able to send another response code, because the original response code was already commited and sent to the client.
Your description of the error and knowledge of the http-protocol implies that there is probably some implementation error in the framework / server components used, OR it was done deliberatly, risking the situation that you are in now...
to redirect a page , you need to set redirect information in header. but you can write header once you start writing content ( may be header is already received by client by the time you compete writing whole document )
But, you can do it in different way as below
1.let document loading complete and record if you need to redirect the page while rendering
2. add a unique request-id identifier for each page load
3. invoke ajax call with request-id ( may be rest call) to server asking if page needs to be redirected.
4. if page needs to be redirected , do so, via javascript in browser at client end.
A HTTP response consists of headers and an optional response content.
Once you have started to write the response to the socket connection you can't revert it. In your example: If you run into an error in the middle of content generation you can't add a redirect header - the header section has already be written.
The statement above is not entirely true: in HTTP chunked transfer encoding the response is sent in separate chunks. The last chunk can have an optional trailer containing entity-header fields and theoretically a redirect header. But if you can use these mechanism is a different question. For instance a servlet container may use chunked transfer encoding but does not give you an API to set the trailer.
But writing must not start immediately: For instance HttpServletResponse maintains a buffer for the response content. If you set headers and start writing the content only the buffer is filled and you still can reset the response and start all over. But once the buffer overflows the response is written to the connection and the HttpServletResponse is now committed.
Such a mechanism gives you way to deal with errors during content generation which happen when the response is not yet committed: Just reset the response and send an error message instead. You could examine your framework if it supports such an mechanism. But obviously this is not a solution for larger responses.
A second way to avoid errors during content generation is simply to make sure that they can't happen. First gather all your data needed for the response (e.g. making unsafe database calls), then in a second step generate the response - the second now step should not fail (except if you have bugs in your code).
You already mentioned a third way to handle an error, by having the client sanitize the response and take some action it errors are detected (e.g. by including a script in the generated HTML response).
The only reliable way to do this is to create a proxy HttpServletResponse object that caches the response. You'd need to give the uPortal this proxy instead of the actual HttpServletResponse, and only send the output using the real response once the processing completes / send redirect if the processing fails.
It is HTTP protocol design limitation that you cannot send HTTP redirect once output was started.
Other possible ways rely on HTML or Javascript redirects, but since you write that the error may happen at any moment, it would be difficult to print it out in a way that the browsers would reliably interpret it as redirect.

How to get the status of a request by another request?

Let me explain what I am doing first:
I have a servlet that handles some GET, POST and PUT requests.
Now on my PUT request I am saving a file from the request.inputStream. Now I want to do some things like I issue another GET request that can give me the status of reading the input stream of that previous request. I can issue an PUT request that can put some binary data with range for that file I am saving previously. Or I can send a DELETE request that will cancel the upload.
How can I do that? How can I access one request from another?
You could use the HttpSession object on the request and save the bytes read on the InputStream.
The session attribute will be accessible on the following request.

Check if a URL's mimetype is not a web page

I want to check if a URL's mimetype is not a webpage. Can I do this in Java? I want to check if the file is a rar or mp3 or mp4 or mpeg or whatever, just not a webpage.
You can issue an HTTP HEAD request and check for Content-Type response headers. You can use the HttpURLConnection.setRequestMethod("HEAD") before you issue the request. Then issue the request with URLConnection.connect() and then use URLConnection.getContentType() which reads the HTTP headers.
The bonus of using a HEAD request is that the actual resource is never transmitted/generated. You can also use a GET request and inspect the resulting stream using URLConnection.guessContentTypeFromStream() which will inspect the actual bytes and try to guess what the stream represents. I think that it looks for magic numbers or other patterns in the stream.
There's nothing inherent in a URL which will tell you what you will receive when you request it. You have to actually request the resource, and then inspect the content-type header. At that point, it's still not clear what you should do - some content types will (almost) always be handled by the browser, e.g. text/html. Some types should be handled by a browser, e.g. application/xhtml+xml. Some types may be handled by the browser, e.g. application/pdf.
Which, if any, of these you consider to be "webpage" is still not clear - you'll need to decide for yourself.
You can inspect the content-type header once you're requested the resource, using, for example, the HttpURLConnection class.
content-type:text/html represents webpage.

How to add a response header before forwarding to another resource

I hava a servlet which handles some resources files, and I need to add a response header before I forward the request to the real jsp file.
response.setHeader("a", "b");
request.getRequestDispatcher("1.jsp").forward(request, response);
I need to send that header directly to the browser, But it did not work, I tried to use firebug to watch the http request and its response, how can I do that?
Try to use .include(request, response) instead. Probably it's a .forward() feature to fully clean response object before forwarding.
See http://download.oracle.com/javaee/5/api/javax/servlet/RequestDispatcher.html
How do you know that it is not working? Please read this JR thread, I believe you are expecting similar thing.
If you want to use some data added by the servlet in the 1.jsp code, I suggest you use request.setAttribute method. response.addHeader/setHeader put some data into the response'header. Generally the data in the response header is used by the browser.
The headers are being cleaned up. Just curious, what stops you from using request.setAttribute()?

Categories

Resources