Do I need to close Response.body for Custom Error Handling in Feign Client - netflix-feign

I have defined custom ErrorDecoder for Feign Client with reference to this wiki page.
In my ErrorDecoder I am reading response body by invoking response.body()
Do I need to close response in my ErrorDecoder when reading InputStream. Or Feign will handle closing of response?
I checked SynchronousMethodHandler which invokes custom error decoder. This has finally block
} finally {
if (shouldClose) {
Util.ensureClosed(response.body());
}
Since there is no guidelines from the wiki page.

If you are reading the Response object directly you must close the body yourself, our you will leak resources. This is also true if you return Response objects as part of your Feign interface.

Related

Aspects from HttpServletResponse's sendError method explained by the official documentation

I am in reference to HttpServletResponse's sendError method:
void sendError(int sc,
java.lang.String msg)
throws java.io.IOException
... and the official documentation provided:
Sends an error response to the client using the specified status and
clears the buffer. The server defaults to creating the response to
look like an HTML-formatted server error page containing the specified
message, setting the content type to "text/html". The server will
preserve cookies and may clear or update any headers needed to serve
the error page as a valid response. If an error-page declaration has
been made for the web application corresponding to the status code
passed in, it will be served back in preference to the suggested msg
parameter and the msg parameter will be ignored.
If the response has
already been committed, this method throws an IllegalStateException.
After using this method, the response should be considered to be
committed and should not be written to.
Can anyone please explain what is meant by "clears the buffer" and "If the response has already been committed"?
what is meant by "clears the buffer"
The code will response.resetBuffer() which basically resets any written and unflushed data of response body.
and "If the response has already been committed"?
If the response headers are already sent to the client. This is a point of no return. The server cannot take back already sent data from the client and re-send a different response.
An example of the normal flow is as below:
user requests JSP
JSP writes some HTML to response body
some awkward code in midst of a JSP file throws an exception
server calls response.sendError(500) so that HTML of HTTP 500 error page will be written
user sees HTTP 500 error page
However, if between step 2 and 3 the response buffer is flushed (i.e. any so far written data gets actually sent from server to client), then the response is in a "committed" state. This cannot be resetted. The enduser basically ends up getting halfbaked HTML output representing the part until the point the exception has occurred.
That's also one of the reasons why doing business logic in a JSP file is a bad practice. See also a.o. How to avoid Java code in JSP files?

What to do with errors when streaming the body of an Http request

How do I handle a server error in the middle of an Http message?
Assuming I already sent the header of the message and I am streaming the
the body of the message, what do I do when I encounter an unexpected error.
I am also assuming this error was caused while generating the content and not a connection error.
(Greatly) Simplified Code:
// I can define any transfer encoding or header fields i need to.
send(header); // Sends the header to the Http client.
// Using an iterable instead of stream for code simplicity's sake.
Iterable<String> stream = getBodyStream();
Iterator<String> iterator = stream.iterator();
while (iterator.hasNext()) {
String string;
try {
string = iterator.next();
catch (Throwable error) { // Oops! an error generating the content.
// What do i do here? (In regards to the Http protocol)
}
send(string);
}
Is there a way to tell the client the server failed and should either retry or abandon the connection or am I sool?
The code is greatly simplified but I am only asking in regards to the protocol and not the exact code.
Thank You
One of the following should do it:
Close the connection (reset or normal close)
Write a malformed chunk (and close the connection) which will trigger client error
Add a http trailer telling your client that something went wrong.
Change your higher level protocol. Last piece of data you send is a hash or a length and the client knows to deal with it.
If you can generate a hash or a length (in a custom header if using http chunks) of your content before you start sending you can send it in a header so your client knows what to expect.
It depends on what you want your client to do with the data (keep it or throw it away). You may not be able to make changes on the client side so the last option will not work for example.
Here is some explanation about the different ways to close. TCP option SO_LINGER (zero) - when it's required.
I think the server should return a response code start with 5xx as per RFC 2616.
Server Error 5xx
Response status codes beginning with the digit "5" indicate cases in which the server is aware that it has erred or is incapable of performing the request. Except when responding to a HEAD request, the server SHOULD include an entity containing an explanation of the error situation, and whether it is a temporary or permanent condition. User agents SHOULD display any included entity to the user. These response codes are applicable to any request method.

Spring RestTemplate - http GET with request body [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
HTTP GET with request body
I've read few discussions here which do not advocate sending content via HTTP GET. There are restrictions on the size of data that can be sent via clients (web browsers). And handling GET data also depends on servers. Please refer section Resources below.
However, I've been asked to test the possibility to send content via HTTP GET using RestTemplate. I refered few discussions on spring forum but they were not answered. (Please note sending data via http Post works fine). The discussion here suggests using POST instead.
dev env - JBoss AS 5.1, Spring 3.1.3
Client
#Test
public void testGetWithBody()
{
// acceptable media type
List<MediaType> acceptableMediaTypes = new ArrayList<MediaType>();
acceptableMediaTypes.add(MediaType.TEXT_PLAIN);
// header
HttpHeaders headers = new HttpHeaders();
headers.setAccept(acceptableMediaTypes);
// body
String body = "hello world";
HttpEntity<String> entity = new HttpEntity<String>(body, headers);
Map<String, Object> uriVariables = new HashMap<String, Object>();
uriVariables.put("id", "testFile");
// Send the request as GET
ResponseEntity<String> result = restTemplate.exchange(
"http://localhost:8080/WebApp/test/{id}/body",
HttpMethod.GET, entity, String.class, uriVariables);
Assert.assertNotNull(result.getBody());
}
Server #Controller
#RequestMapping(value = "/{id}/body", method = RequestMethod.GET)
public #ResponseBody
String testGetWithBody(#PathVariable String id,
#RequestBody String bodyContent)
{
return id + bodyContent;
}
The problem -
executing this test case returns 500 Internal Server Error. On debugging, I found that the controller is not hit.
Is it correct to understand that the RestTemplate provides the way to send data as request body, but the error occurs because the server could not handle the request body ?
If the request body sent via HTTP Get is not conventional why does RestTemplate provide the APIs to allow sending it ? Does this mean there are few servers capable of handling the Request body via GET ?
Resources - discussions on sending body via HTTP GET using RestTemplate at spring forum
http://forum.springsource.org/showthread.php?129510-Message-body-with-HTTP-GET&highlight=resttemplate+http+get
http://forum.springsource.org/showthread.php?94201-GET-method-on-RestTemplate-exchange-with-a-Body&highlight=resttemplate+http+get
Resources - General discussions on sending body via HTTP GET
get-with-request-body
is-this-statement-correct-http-get-method-always-has-no-message-body
get-or-post-when-reading-request-body
http-uri-get-limit
Is it correct to understand that the RestTemplate provides the way to send data as request body, but the error occurs because the server could not handle the request body ?
You can tell by looking at network traffic (does the request get sent with a request body and a GET method?) and at server logs (the 500 result you receive must have a server-side effect that gets logged, and if not, configure the server to do so).
If the request body sent via HTTP Get is not conventional why does RestTemplate provide the APIs to allow sending it ? Does this mean there are few servers capable of handling the Request body via GET ?
Because it is a generic class that also allows you to craft requests that can include a message body.
As stated in HTTP GET with request body:
In other words, any HTTP request message is allowed to contain a message body, and thus [a server] must parse messages with that in mind. Server semantics for GET, however, are restricted such that a body, if any, has no semantic meaning to the request. The requirements on parsing are separate from the requirements on method semantics.
A body on a GET cannot do anything semantically, because you are requesting a resource. It's like you tell the server: "Give me resource X, oh, and have some apples!". The server won't care about your apples and happily serve resource X - or throw an error because it doesn't like any offers in a request.
However, I've been asked to test the possibility to send content via HTTP GET
Please tell the one who requested this that this is a case that should not have to be tested, because no sensible implementation supports it.

ASP.NET XMLHTTPREQUEST download file using Handler

am trying to implement file download using xmlhttprequest... But am not getting the file dialog or any response. I have debug the handler, no error.
function download(id)
{
try
{
var xmlHttp=new XMLHttpRequest();
xmlHttp.open("GET","DownloadFileHandler.ashx?id=" + id,false);
xmlHttp.send();
xmlHttp.onreadystatechange=function()
{
//if request has been entertained and response is returned from server
if(xmlHttp.readyState==4)
{
alert("aq");
}
}
}
catch (ex)
{
alert("Browser does not support ajax");
}
}
}
my handler
context.Response.AppendHeader("content-disposition", "attachment; filename=" + name);
context.Response.ContentType = type;
context.Response.WriteFile(path);
context.Response.End();
So, clearly AJAX uses a XML based http requests. This is a different
protocol than a file download request. A file download is a binary
http request.
First, while the XmlHttpRequest object can parse the data to XML, you can also get the full data, be it binary or not. You can parse it into whatever you want.
Second, it is not a different protocol. The protocol is HTTP. HTTP is transferring the data, and doing content negotiation, in both cases.
Third, HTTP GET requests (the same kind of request in both cases) can return binary or textual data entirely independent on how the request is generated. A request can be generated through an tag, or a user clicking an link, or an XMLHttpRequest, and the content type (binary or text) is totally independent of how the request was generated.
The real reason you can't download a file using XMLHttpRequest, but instead have to use browser-specific extensions such as nsIWebBrowserPersist, is that browsers have chosen to not pay attention to the Content-Disposition header when reading data returned from an XMLHttpRequest, the way they do when reading data for a top-level page (or -- you can trigger a download by getting data through an invisible iframe)
Personally, I think this is a poor choice by web browsers, because there is no extra security, only inconvenience for developers. There's no way to send Accept: headers or verbs other than GET by issuing requests with an IFRAME or IMG element, so you can't control content negotiation. Instead, you have to escape the HTTP protocol into GET parameters, which I find sad and un-REST-ful.
For more information on nsIWebBrowserPersist, see https://developer.mozilla.org/en/Code_snippets/Downloading_Files
Notice in your code you have:
var xmlHttp=new XMLHttpRequest();
So, clearly AJAX uses a XML based http requests. This is a different protocol than a file download request. A file download is a binary http request.
Kinda like speaking two different languages when there is no translator. Doesn't work...
So, one solution is to create a link which points to a .ashx handler which can get the file and send it to the client

How to Modify the HTTP Response Using Filters in asp.net?

Modifying the HTTP Response Using Filters
I think the question relates to ASP.NET, not Java. This might help:
http://professionalaspnet.com/archive/2008/04/13/What-is-the-Difference-between-an-httpModule-and-an-httpHandler_3F00_.aspx
These kind of components are called filters in the Java world. They are capable of modifying requests/responses before they are dispachted to the handler component resp. before the response is delivered to the client.
In ASP.NET these kind of components are called HTTP Modules.
Historically, response filters have been the way to do this in ASP.NET. However, they suffer from some serious cache-related issues, both in IIS6 (tougher to notice) and IIS7. This question includes a KB article with more detail.
Use:
response
Purpose
The response object is an instance of the Servlet API's
HttpServletResponse class
Examples
class BookController {
def downloadFile = {
byte[] bytes = // read bytes
response.outputStream << bytes
}
}
Description
The Servlet API's HttpServletResponse class can be used within
Grails to perform all typical activities such as writing out binary
data, writing directly to the response and sending error response
codes to name but a few.
Quoted from here.

Resources